Muh*_*eed 3 .net c# design-patterns ioc-container inversion-of-control
我有以下几个依赖的基类:
public abstract class ViewModel
{
private readonly ILoggingService loggingService;
public ViewModel(
ILoggingService loggingService,
...)
{
this.loggingService = loggingService;
...
}
}
Run Code Online (Sandbox Code Playgroud)
在我的派生类中,我不想重复此基类构造函数中的所有参数,所以我这样做:
public abstract class ViewModel
{
private readonly IUnityContainer container;
private ILoggingService loggingService;
...
public ViewModel(IUnityContainer container)
{
this.container = container;
}
public ILoggingService LoggingService
{
get
{
if (this.loggingService == null)
{
this.loggingService = this.container.Resolve<IUnityContainer>();
}
return this.loggingService;
}
}
...
}
Run Code Online (Sandbox Code Playgroud)
现在我的派生类只需要将一个东西传递给我的基类构造函数.我也有很好的效果,只有在需要时才能解析我的依赖项.
但是,我已经知道传递一个IOC容器是一个坏主意.什么是最好的替代设计模式,记住传入的许多服务已经作为单身人士在我的IOC容器中注册?
如你所述,你应该避免绕过容器.这会把它变成一个"持有袋",在那里你再也看不到你的依赖,你不能轻易看到包里有什么.
相反,如果你发现你的构造函数需要太多参数,这本身就是一种气味.在这种情况下,您经常会发现您的班级正在尝试做太多事情(这违反了单一责任原则).
查看参数列表,看看是否可以将参数分组为更小的组.例如,如果您的构造函数需要IEmailSender
,IEventLog
并且ILoggingService
您可能真正需要的是INotificationService
聚合这三个依赖项的内容.
当然,有时你做的有很多依赖关系的构造.在这种情况下,该类可能只是用于将这些东西聚集在一起并将它们连接起来.如果是这种情况,班级应该避免做任何实际的工作.
小智 6
在构造函数中传递所有依赖项是最干净的方法.
我没有看到在派生类中传递参数的问题.避免打字是错误的动机,有一些像Resharper这样的工具可以帮助你生成这些构造函数.
如果您有很多依赖项,则表明该类违反了单一责任模式.
在许多情况下,它也很好地考虑使用Composition而不是继承.这也有助于将类拆分为不违反SRP的较小部分.