【问题标题】:How to make a class use different implementations of injected dependencies?如何使一个类使用注入依赖项的不同实现?
【发布时间】:2016-09-09 07:17:57
【问题描述】:

想象一下我有这些课程:

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 是一样的。但是,不同之处在于我使用Ninject 为这些类注入了ISomething1ISomething2 的不同实现:

//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 原则。但是,我喜欢它,因为它遵循开放/封闭原则(我希望如此)。

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

【问题讨论】:

  • 对我来说这看起来像是一种代码味道,因为正如你所说,类是相同的。它们仅在运行时不同。没有关于 MyClass1/2 对象生命周期的任何信息,猜测是使用工厂模式。
  • @rboe 你的意思是在MyClass 内使用ISomething1ISomething2 的工厂?
  • @rboe 类似_something1Factory.Get(someType).Calculate(anotherObject.Property1) ?
  • 不在“MyClass”内。 'MyClass1' 和 'MyClass2' 将合并为 'MyClass' (也许不再需要 IMyClass 接口)并且有一个工厂(或多个)创建 'IMyClass' 实例。
  • @rboe 工厂将创建哪些实例?你说只有一个实例 - MyClass

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


【解决方案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());
    }
}

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

【讨论】:

猜你喜欢
  • 1970-01-01
  • 2023-03-14
  • 2014-01-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-08-25
  • 2016-11-08
  • 2011-05-06
相关资源
最近更新 更多