我的应用程序处理多个客户端,每个客户端都有不同的设置。
所以我决定使用IOC容器使用key
注册每个客户端特定的设置。然后我根据key
找到ClientSettings。 key
值将在运行时期间可用。
C#Library MyCompany.BO
public class ClientSettings : IClientSettings
{
public string ClientApiKey { get; private set}
public string ClientId { get; private set}
public static IClientSettings Load(string clientname)
{
// Load the client specific information from JSON file using clientname
var cs = new ClientSettings();
cs.ClientApiKey = "Some client specific key";
cs.ClientId = "Some client specific key";
return cs;
}
}
在MyCompany.BO名称空间中使用
public class RuleEngine : IRuleEngine
{
IFactory _factory;
RuleEngine(IFactory factory)
{
factory = _factory;
}
public void Run(string request)
{
var clientname = ParseStringToGetClientName(request)
var clientSettings = ServiceLocator.Current.GetInstance<IClientSettings>(clientname);
var service = _factory.GetService(clientname);
service.DoWork(clientSettings);
}
}
主要应用程序注册客户端设置
var container = new UnityContainer();
var clientASettings = ClientSettings.Load("ClientA");
var clientBASettings = ClientSettings.Load("ClientB");
var clientCSettings = ClientSettings.Load("ClientC");
// register singleton instance
container.RegisterInstance("ClientA", clientASettings);
container.RegisterInstance("ClientB", clientBSettings);
container.RegisterInstance("ClientC", clientCSettings);
问题
RuleEngine类正在使用Microsoft.Practices.ServiceLocation.ServiceLocator
根据ClientSettings
找到key
。这意味着实现规则引擎的C#库需要使用应用程序正在使用的相同IOC。 (在这种情况下是Unity)
如何让图书馆不知道IOC容器?
如果在运行时期间已知key
值,如何在不使用ServiceLocator的情况下在此处注入客户端设置?
工厂模式是实现这一目标的唯一途径吗? (例如,我找到服务的方式_factory.GetService(clientname)
)
答案 0 :(得分:4)
这三行:
var clientname = ParseStringToGetClientName(request);
var clientSettings = ServiceLocator.Current.GetInstance<IClientSettings>(clientname);
var service = _factory.GetService(clientname);
看起来像纯管道,很少或没有分支。将该部分移至Composition Root。既然您已put this in your Composition Root,那么您可以使用no reason to attempt to abstract away any DI Container。相反,您可以使用DI Container的API简单地编写所需的服务,而可重用的类库将不需要知道发生的情况。