替代传递IOC容器

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容器中注册?

Rog*_*mbe 9

如你所述,你应该避免绕过容器.这会把它变成一个"持有袋",在那里你再也看不到你的依赖,你不能轻易看到包里有什么.

相反,如果你发现你的构造函数需要太多参数,这本身就是一种气味.在这种情况下,您经常会发现您的班级正在尝试做太多事情(这违反了单一责任原则).

查看参数列表,看看是否可以将参数分组为更小的组.例如,如果您的构造函数需要IEmailSender,IEventLog并且ILoggingService您可能真正需要的是INotificationService聚合这三个依赖项的内容.

当然,有时你做的有很多依赖关系的构造.在这种情况下,该类可能只是用于将这些东西聚集在一起并将它们连接起来.如果是这种情况,班级应该避免做任何实际的工作.


小智 6

在构造函数中传递所有依赖项是最干净的方法.

我没有看到在派生类中传递参数的问题.避免打字是错误的动机,有一些像Resharper这样的工具可以帮助你生成这些构造函数.

如果您有很多依赖项,则表明该类违反了单一责任模式.

在许多情况下,它也很好地考虑使用Composition而不是继承.这也有助于将类拆分为不违反SRP的较小部分.