构造函数依赖地狱

时间:2019-07-02 04:26:46

标签: c# constructor dependencies

我尝试使用尽可能多的接口来进行良好的单元测试和更好地理解程序体系结构。

尽管我尝试遵循SOLID规则-我的类需要在构造函数中传递很多依赖关系,但这会变成地狱。

通过搜索,我找到了IoC容器,但实际上我不太了解何时使用它们。在构造函数中传递NInject内核看起来很愚蠢,仅使用NInject创建主类并不能消除构造函数中存在大量参数的问题。

我无法减少构造函数中的依赖项数量。我不明白如何正确使用NInject减少构造函数参数。我该如何解决这个问题?

(不是最糟糕的例子)

public SomeConstructor(ISettings settings, INotification notification, IServer server, IPriceCache priceCache)
{
    Settings = settings;
    Notification = notificartion;
    Server = server;
    PriceCache = priceCache;
}

(这个解决方案看起来很糟糕)

public SomeConstructor(IKernel ninjectKernel)
{
    Settings = ninjectKernel.Get<ISettings>();
    Notification = ninjectKernel.Get<INotification>();
    Server = ninjectKernel.Get<IServer>();
    PriceCache = ninjectKernel.Get<IPriceCache>();
}

2 个答案:

答案 0 :(得分:0)

如果您不需要构造函数中的任何内容,那么Ninject允许您使用带有属性的Property Setter Injection。看起来像这样:

class Samurai 
{    
    [Inject]
    public IWeapon Weapon { private get; set; }

    public void Attack(string target) 
    {
        this.Weapon.Hit(target);
    }
}

但是正如我在上面的评论中提到的那样。所有这些工作实际上都具有相同的效果,只是因为您没有在构造函数中包含这些项并不会改变您认为代码具有大量依赖项的事实。

答案 1 :(得分:0)

使用IoC / DI的原因之一是摆脱了生命周期范围的责任-也就是说,组件应该 request 依赖项(例如,通过构造函数注入或属性注入),但不应这样做拥有它们。

因此,应该有一些其他的类,通常称为 container ,用于管理生命周期范围和依赖项。

在(理想的)组织良好的体系结构中,您永远不会调用服务的解决方案-在容器中注册所有服务,然后让它们运行-然后容器将创建组件并为它们解决必要的依赖关系(维护创建和处置,在各种生命周期范围内都是必要的。

因此,您几乎“正确”地执行了所有操作,但只是缺少了这种“容器”概念。