我在项目中使用依赖注入有一个小问题。为了描述问题,我将使用简单的例子。让我们假设我正在编写记录器应用程序,我的最终用户可以选择是将日志保存到文件还是写入控制台。用户通过选择运行应用程序中的复选框来控制它。他可以选择两者或仅选择一种。选择后,单击“LOG”按钮执行操作。 现在,根据我对DI的了解,我应该创建接口:
public interface ILogger
{
void log();
}
两个实现
public class ConsoleLogger : ILogger
{
public void log()
{
...
}
}
public class FileLogger : ILogger
{
public void log()
{
...
}
}
我知道我可以在例如统一容器中注册两个实现并通过使用表在构造函数中获取它们然后我无法识别哪些实现是FileLogger,哪个是ConsoleLogger(如果用户只选择一个复选框)< / p>
第二个选项是使用服务定位器模式来按名称解析来自ioc的实现。我不知道这是不是一个好方法
在我的实际应用程序中,我将有两个以上的选项,每个选项都会有很多共享接口。
也许更好的是使用MEF?
申请将以WPF + PRISM编写。
答案 0 :(得分:3)
我通常这样做的方法是让你的班级依赖于ILoggerFactory
,这可以创建一个名称的ILogger
个实例。
工厂实现LoggerFactory
将保存容器的内核,并能够按名称解析组件。
注意工厂界面如何只告诉你它可以创建对象 - 它没有给你任何关于任何底层内核或DI框架的提示 - 工厂实现是了解这些细节的。
这样的事情:
public class MyLoggingClass
{
private readonly ILoggerFactory _loggerFactorty;
public MyLoggingClass(ILoggerFactory factory)
{
_loggerFactorty = factory;
var fileLogger = _loggerFactorty.Create("fileLogger");
var consoleLogger = _loggerFactorty.Create("consoleLogger");
}
}
public class LoggerFactory : ILoggerFactory
{
public ILogger Create(string key)
{
return kernel.Resolve<ILogger>(key);
}
}
像温莎城堡这样的框架甚至可以免费为您提供这些工厂:您甚至不必编写其实施。
答案 1 :(得分:2)
服务定位器模式现在是反模式,不应使用。
在您的情况下,最好使用Strategy design pattern,因为您在运行时动态创建对象。
依赖注入和策略模式之间的差异是微妙的,但有。有关更多信息:
Strategy Pattern vs Dependency Injection
What is the difference between Strategy pattern and Dependency Injection?
要动态创建对象,您可以使用factory method设计模式或abstract factory。
答案 2 :(得分:0)
如果你想要的只是基本的IOC功能,我没有看到创建自定义工厂的重点。如果您要使用WPF和Prism开发应用程序,一个好方法是使用一个受支持的IOC容器。我经常使用Unity,非常喜欢它。另一个支持的版本是MEF(如您所建议的)。
它们都允许您使用名称解析接口。这是不错的做法,并提供了一种解决正确接口的结构化方法。
使用Prism with Unity或Mef,请参见此处:
http://msdn.microsoft.com/en-us/library/gg430868(v=pandp.40).aspx