依赖注入和许多接口实现方式

4

我是一名有用的助手,可以为您翻译文本。

我在使用依赖注入时遇到了一个小问题。为了描述这个问题,我将使用一个简单的例子。假设我正在编写记录器应用程序,我的最终用户可以选择将日志保存到文件还是写入控制台。用户通过在运行应用程序时选择复选框来控制它。他可以选择两者或仅选择其中一个。选择后,他点击“LOG”按钮执行操作。 现在根据我对DI的理解,我应该创建接口:

public interface ILogger
{ 
   void log();
}

还有两种实现方式

public class ConsoleLogger : ILogger
{
    public void log()
    {
      ...
    }
}

public class FileLogger : ILogger
{
    public void log()
    {
      ...
    }
}

我知道我可以在例如Unity容器中注册两个实现,并使用表格在构造函数中获取它们,但是如果用户只选择一个复选框,则无法识别哪个实现是FileLogger,哪个是ConsoleLogger。
第二个选择是使用服务定位器模式按名称从IOC解析实现。我不知道这是否是一个好方法。
在我的真实应用程序中,我将拥有比两个更多的选项,并且每个选项都将有很多共享接口。
也许更好的方法是使用MEF?
应用程序将使用WPF + PRISM编写。
3个回答

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);
    }
}

像Castle Windsor这样的框架甚至免费为您提供这些工厂:您甚至不必编写它的实现。


我明白所有的工厂都应该是我的组合根。谢谢! - niba

2

0

我不明白如果你只需要基本的IOC功能,为什么要创建自定义工厂。如果你用WPF和Prism开发应用程序,一个好的方法是使用其中一个支持的IOC容器。我经常使用Unity并且很喜欢它。另一个支持的版本是MEF(正如你建议的)。

两者都允许您使用名称解析接口。这不是坏习惯,而是提供了一种结构化的方式来解决正确的接口。

想要使用Prism与Unity或Mef,请参见此处:

https://learn.microsoft.com/en-us/previous-versions/msp-n-p/gg430868(v=pandp.40)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接