views:

68

answers:

2

hi all,

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 ActualDevice : IActualDevice
{}

public SimulatedActualDevice : IActualDevice
{}

public 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.

Adiel.

A: 

1) This is totally bad idea, because interfaces are intended to hide details of implementation. Use IDevice type everywhere and inject this dependency manually

IDevice d;

if(a == 1)
{
   d = container.Resolve<SimulatedActualDevice>()
}
else
{
   d = container.Resolve<ActualDevice>()
}

User user = container.Resolve<IUser>();
user.Device = d;

If you do not want to use implementation class names in code, then use named registrations:

IDevice d;

if(a == 1)
{
   d = container.Resolve<IDevice>("Simulated")
}
else
{
   d = container.Resolve<IDevice>("Actual")
}

User user = container.Resolve<IUser>();
user.Device = d;

2) Events subscription between objects is part of initialization of the object but not part of creation. Unity just encapsulates "new" operators. Make subscriptions in constructors or in special factories like you did before using DI container.

Yauheni Sivukha
-1 This answer both recommend **Tight Coupling** and the **Service Locator anti-pattern** - both spectacularly bad ideas.
Mark Seemann
Tight Coupling is used only as example and actually this is not so bad idea with "Strategy" pattern. As for Service locator - please suggest another way. The most common example - How to create objects of different strategies dynamically?
Yauheni Sivukha
Abstract Factory
Mark Seemann
Yes, and how will you will implement such abstract factory? Manually create object like in http://stackoverflow.com/questions/1926826/cant-combine-factory-di/1927167#1927167? In that case yours abstract factory will have bunch of unnecessary dependencies. It is much better to use Tight Coupling and the Service Locator while implementation of that factory.
Yauheni Sivukha
See my comment over at that question.
Mark Seemann
+1  A: 

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.

Mark Seemann
exactly the answer i was looking for the first question. i suggested the "Leaky abstraction" while knowing its ugly just to for disucssion sake as to clarify my point.As to my second question i think of having an AppFactory which will make produce the "Glue" - all the event subscription between the events. what do you say ?
Adiel
You may want to look at Domain Events: http://msdn.microsoft.com/en-us/magazine/ee236415.aspx
Mark Seemann