Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

IoC - Multiple implementations support for a single interface

I am wondering why .Net IoC containers do not easily support multiple implementations for a single interface! May be I am wrong, but as far I have seen, frameworks like Ninject partially supports this feature using annotations (how?). I do not think other frameworks like Windsor or simple injector have an easy mechanism to support this scenario.

Is there any reason why this is not supported by many frameworks? AFAIK, one of the most important reasons to use interfaces is to achieve loose coupling. If the frameworks designed to improve loose coupling, do not fluently support multiple implementations for a single interface, I do not understand why!

P.S. Of course I understand that there will be a resolution issue during run time, and the container would be confused which implementation to choose, but that is something which has to be considered in the design, right?

like image 772
Bala Avatar asked Jul 29 '12 10:07

Bala


People also ask

Can an interface have multiple implementations?

Two interfaces with same methods having same signature but different return types. Java does not support multiple inheritances but we can achieve the effect of multiple inheritances using interfaces. In interfaces, a class can implement more than one interface which can't be done through extends keyword.

CAN interface have multiple implementations C#?

Multiple implementations with generic Language limitation, but probably in the future, C# allows you to do it. This interface has three implementations, Cat, Dog, and Human class. To register, add this code.

What is dependency injection What are the benefits of using an IoC container?

A basic benefit of dependency injection is decreased coupling between classes and their dependencies. By removing a client's knowledge of how its dependencies are implemented, programs become more reusable, testable and maintainable.


2 Answers

Unity has the same functionality

Register named dependency

    var container = new UnityContainer();
    container.RegisterType<IConnector, Connector>("TestConnector");

Resolve by name

    container.Resolve<IConnector>("TestConnector");

the same approach

    [Dependency("TestConnector")]
    public IConnector Connector { get; set; }

Windsor has the same

class Program
{
    static void Main(string[] args)
    {
        var container = new WindsorContainer()
            .Register(Component.For<IConnector>().ImplementedBy<ConnectorA>().Named("ConnectorA"))
            .Register(Component.For<IConnector>().ImplementedBy<ConnectorB>().Named("ConnectorB"));

        var connectorA = container.Resolve<IConnector>("ConnectorA");
        Console.WriteLine("Connector type: {0}", connectorA.GetType());
        var connectorB = container.Resolve<IConnector>("ConnectorB");
        Console.WriteLine("Connector type: {0}", connectorB.GetType());
        Console.ReadKey();
    }
}

public interface IConnector
{
}

public class ConnectorA : IConnector
{

}

public class ConnectorB : IConnector
{

}
like image 173
GSerjo Avatar answered Oct 12 '22 05:10

GSerjo


I advice to look at Convention over Configuration and especially Convention Based Dependency Injection and context-based dependency injection. Most of IoC if not all supports both approaches. You could find many interesting samples with different IoC libraries, when several implementation bind to one interface, and how useful it could be.

For example ninject does support binding of several implementation of one interface: depends on context or attributes, by names, and so one.

By context

Following snippet binds on implemetation depends on target type automaticaly:

Bind<IWarrior>().To<Samurai>().WhenInjectedInto(typeof(OnLandAttack));
Bind<IWarrior>().To<SpecialNinja>().WhenInjectedInto(typeof(AmphibiousAttack));

By name

Very helpful when you configuration is in XML or database. Take into account InNamedScope also:

Bind<IWeapon>().To<Shuriken>().Named("Strong");
Bind<IWeapon>().To<Dagger>().Named("Weak");

By convention

With different dependency configuration at different parts of your project.

like image 20
Akim Avatar answered Oct 12 '22 06:10

Akim