[英]Dependency injection and many implementations of interface
I have a small problem with using dependency injection in my project.在我的项目中使用依赖注入有一个小问题。 To describe problem I will use simple example.为了描述问题,我将使用简单的示例。 Let's assume that I'm writing logger aplication and my end user is able to choose if log should be saved to file or written to the console.假设我正在编写记录器应用程序,并且我的最终用户能够选择是否应将日志保存到文件或写入控制台。 User control it by choosing checkboxes in running app.用户通过在运行的应用程序中选择复选框来控制它。 He can select both or only one.他可以 select 两者或仅一个。 After selecting he clicks button "LOG" to perform action.选择后,他单击“LOG”按钮执行操作。 Now what I understand from my knowledge of DI I should create interfaces:现在,根据我对 DI 的了解,我应该创建接口:
public interface ILogger
{
void log();
}
And two implementations和两个实现
public class ConsoleLogger : ILogger
{
public void log()
{
...
}
}
public class FileLogger : ILogger
{
public void log()
{
...
}
}
I know that I can register both implementations in for example unity container and get them in constructor by using table but then I can't identify which implementations is FileLogger and which is ConsoleLogger (In case when user select only one checkbox)我知道我可以在例如统一容器中注册这两个实现,并通过使用表在构造函数中获取它们,但是我无法确定哪些实现是 FileLogger,哪些是 ConsoleLogger(如果用户 select 只有一个复选框)
Second options is use service locator pattern to resolve implementations from ioc by name.第二种选择是使用服务定位器模式通过名称解析来自 ioc 的实现。 I dont know if it is a good approach我不知道这是否是一个好方法
In my real application I will have more options than two and there will be a lot of shared interfaces by each option.在我的实际应用程序中,我将有两个以上的选项,并且每个选项都会有很多共享接口。
Maybe better is use MEF?也许更好的是使用MEF?
Application will be written in WPF + PRISM.应用程序将写入 WPF + PRISM。
The way I usually do this is to make your class depend on an ILoggerFactory
, which can create ILogger
instances given a name.我通常这样做的方式是让您的 class 依赖于ILoggerFactory
,它可以创建ILogger
实例给定名称。
The factory implementation, LoggerFactory
, would hold the container's kernel and be able to resolve the component by name.工厂实现LoggerFactory
将保存容器的 kernel 并能够按名称解析组件。
Notice how the factory interface only tells you that it can create objects - it doesn't give you any hint about any underlying kernel, or DI framework - the factory implementation is the one that knows about those details.请注意,工厂接口如何只告诉您它可以创建对象 - 它没有给您任何有关任何底层 kernel 或 DI 框架的提示 - 工厂实现是了解这些细节的那个。
Something like this:像这样的东西:
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);
}
}
Frameworks like Castle Windsor even give you these factories for free: you don't even have to write its implementation.像 Castle Windsor 这样的框架甚至免费为您提供这些工厂:您甚至不必编写它的实现。
Service locator pattern is an anti-pattern now and should not be used.服务定位器模式现在是一种反模式,不应使用。
In your case, it's better to use Strategy design pattern because you're creating objects dynamically at runtime.在您的情况下,最好使用策略设计模式,因为您在运行时动态创建对象。
The differences between dependency injection and strategy pattern are subtle but there are.依赖注入和策略模式之间的差异是微妙的,但确实存在。 For more information:了解更多信息:
Strategy Pattern vs Dependency Injection 策略模式与依赖注入
What is the difference between Strategy pattern and Dependency Injection? 策略模式和依赖注入有什么区别?
To create objects dynamically, you could use factory method design pattern or abstract factory .要动态创建对象,您可以使用工厂方法设计模式或抽象工厂。
I don't see the point of creating a custom factory if all you want is basic IOC functionality.如果您想要的只是基本的 IOC 功能,我看不出创建自定义工厂的意义。 If you're going to develop the application using WPF and Prism, a good approach is to use one of the supported IOC containers.如果您要使用 WPF 和 Prism 开发应用程序,一个好的方法是使用受支持的 IOC 容器之一。 I have used Unity a lot and really like it.我经常使用 Unity,并且非常喜欢它。 Another supported version is the MEF (as you suggested).另一个受支持的版本是 MEF(如您所建议的)。
Both of them allow you to resolve interfaces using names.它们都允许您使用名称解析接口。 It is not bad practice and gives a structured way of resolving the correct interface.这是不错的做法,并提供了解决正确界面的结构化方法。
For using Prism with Unity or Mef, see here:要在 Unity 或 Mef 中使用 Prism,请参见此处:
https://docs.microsoft.com/en-us/previous-versions/msp-np/gg430868(v=pandp.40) https://docs.microsoft.com/en-us/previous-versions/msp-np/gg430868(v=pandp.40)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.