如何使类使用注入依赖项的不同实现?

时间:2016-09-09 07:17:58

标签: c# oop design-patterns dependency-injection ninject

想象一下,我有这个课程:

public class MyClass : IMyClass
{
    private readonly ISomething1 _something1;
    private readonly ISomething2 _something2;

    public MyClass(ISomething1 something1, ISomething2 something2)
    {
        _something1 = something1;
        _something2 = something2;
    }

    public SomeObject Get(AnotherObject anotherObject)
    {
        var a = _something1.Calculate(anotherObject.Property1);
        var b = _something2.Get(anotherObject.Property2, a);

        return b;
    }
}

public class MyClass2 : IMyClass
{
    private readonly ISomething1 _something1;
    private readonly ISomething2 _something2;

    public MyClass(ISomething1 something1, ISomething2 something2)
    {
        _something1 = something1;
        _something2 = something2;
    }

    public SomeObject Get(AnotherObject anotherObject)
    {
        var a = _something1.Calculate(anotherObject.Property1);
        var b = _something2.Get(anotherObject.Property2, a);

        return b;
    }
}

看起来MyClassMyclass2是相同的。但是,区别在于我使用ISomething1为这些类注入ISomething2Ninject的不同实现:

//MyClass
Bind<ISomething1>().To<AmazingSomething>().WhenInjectedInto<MyClass>();
Bind<ISomething2>().To<BeautifulSomething>().WhenInjectedInto<MyClass>();

//MyClass2
Bind<ISomething1>().To<GoodSomething>().WhenInjectedInto<MyClass2>();
Bind<ISomething2>().To<UglySomething>().WhenInjectedInto<MyClass2>();

我不喜欢这个解决方案,因为它违反了DRY原则。但是,我喜欢它,因为它遵循开放/封闭原则(我希望如此)。

有没有更好的方法来实现我的目标?

1 个答案:

答案 0 :(得分:1)

绝对不需要MyClass2

您很可能需要工厂来创建IMyClass实现,使用一些自定义逻辑来选择,要注入的ISomething1ISomething2实现。

我没有在我的项目中使用Ninject,但我相信,您可以将一些元数据附加到您的依赖项,这将有助于您实现选择逻辑。

例如,使用穷人的DI会有这样的事情:

public class MyClassFactory
{
    public IMyClass Create()
    {
        if (DateTime.Today.DayOfWeek = DayOfWeek.Friday)
        {
            return new MyClass(new ASomething1(), new ASomething2());
        }

        return new MyClass(new BSomething1(), new BSomething2());
    }
}

因此,工厂代码取决于必须如何实例化和组合所有这些对象。