Search code examples
c#design-patternsdependency-injectionunity-container

What are the basic principles of designing under Dependency Injection pattern


I'm new to the all DI pattern idea and i have some basic design doubts. im using Unity application blocks 2.0 as my DI framwork.

To the questions :

  1. Say I have an interface for HW devices named IDevice. And some HW listener that receives such IDevice. Now say you have several HW Devices that implement IDevice and Several Listeners. You need to specify for each listener which actual device to inject. You can’t just map a single device to the interface you need something like multiple mapping.

well one solution possible is to create another level of abstraction for each actual device like

public interface IActualDevice : IDevice { }

public class ActualDevice : IActualDevice { }

public class SimulatedActualDevice : IActualDevice { }

public class OtherAcualDevice : IOtherAcualDevice { }

then it would be possible to create such kind of mapping :

container.RegisterType<IActualDevice, ActualDevice>()

or if the HW is missing :

container.RegisterType<IActualDevice, SimulatedActualDevice>()

so what do you say is this good design ?

  1. DI pattern gives us the good creation of objects mechanism.

What about glue, what about the event subscription between objects ?

don't you think it is missing or better am i missing some Unity feature that supports it.


Solution

  • There's no need to introduce Marker Interfaces to make your DI Container work - that would be a Leaky Abstraction.

    With Unity, you can configure each Listener with its own IDevice implementation like this:

    container.RegisterType<IDevice, ActualDevice>("actual");
    container.RegisterType<IDevice, OtherActualDevice>("otherActual");
    
    container.RegisterType<IListener, Listener1>("listener1",
        new InjectionConstructor(
            new ResolvedParameter<IDevice>("actual")));
    container.RegisterType<IListener, Listener2>("listener2",
        new InjectionConstructor(
            new ResolvedParameter<IDevice>("otherActual")));
    

    You can now resolve the listeners like this:

    var listener1 = container.Resolve<IListener>("listener1");
    var listener2 = container.Resolve<IListener>("listener2");
    

    In general, the core patterns of DI are Constructor Injection and Abstract Factory. Most other things follow from these two. See this answer for more DI patterns and principles.