Yan Ivan Evdokimov
Yan Ivan Evdokimov

Reputation: 179

How to make a class use different implementations of injected dependencies?

Imagine I have this classes:

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;
    }
}

It looks like MyClass and Myclass2 are the same. However, the difference is that I am injecting different implementations of ISomething1 and ISomething2 for these classes using Ninject:

//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>();

I don't like this solution because it violates DRY principle. However, I like it because it is following Open/closed principle (I hope so).

Is there a better way to accomplish my goal?

Upvotes: 0

Views: 50

Answers (1)

Dennis
Dennis

Reputation: 37760

Definitely you don't need MyClass2.

Most likely you need factory to create IMyClass implementations, using some custom logic to choose, what ISomething1 and ISomething2 implementations to inject.

I'm not using Ninject in my projects, but I believe, that you could attach some metadata to your dependencies, and this will help you to implement selection logic.

E.g., using poor man's DI there will be something like this:

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());
    }
}

So, factory code depends on how all these objects must be instantiated and combined.

Upvotes: 1

Related Questions