Geeks With Blogs
Watson Jon Code and ramblings from Watson

If you only have one implementation of a registered interface then it is pretty straight forward, but what do you do if you have multiple implementations of an interface? Now you have to get a little more explicit when registering items in your container. Let’s go through a simple example.

Say you have a class, OrderProcessor, that takes one implementation of IMessageWriter:

    public class OrderProcessor
    {
        private readonly IMessageWriter _messageWriter;
 
        public OrderProcessor(IMessageWriter messageWriter)
        {
            _messageWriter = messageWriter;
        }
 
        public void SubmitOrder()
        {
            // do something special with the order
 
            _messageWriter.Write("Submitting order...");
            
            // do some more with the order
        }
    }

 

IMessageWriter is a simple interface:

    public interface IMessageWriter
    {
        void Write(string message);
    }

 

If we have only one implementation of IMessageWriter then registration is simple:

    class Program
    {
        static void Main(string[] args)
        {
            var container = new UnityContainer();
 
            container.RegisterType<IMessageWriter, ConsoleMessageWriter>();
            
            var orderProcessor = container.Resolve<OrderProcessor>();
 
            orderProcessor.SubmitOrder();
        }
    }

 

In this case our OrderProcessor will use the ConsoleMessageWriter when we call SubmitOrder to write the message to the console. Here’s the implementation of ConsoleMessageWriter:

    public class ConsoleMessageWriter : IMessageWriter
    {
        public void Write(string message)
        {
            Console.WriteLine(message);
        }
    }

 

What if we have two implementations of IMessageWriter? Let’s add DebugMessageWriter:

    public class DebugMessageWriter : IMessageWriter
    {
        public void Write(string message)
        {
            Debug.WriteLine(message);
        }
    }

 

And when we register both types with our IoC container, which one will be used?

    class Program
    {
        static void Main(string[] args)
        {
            var container = new UnityContainer();
 
            container.RegisterType<IMessageWriter, ConsoleMessageWriter>();
            container.RegisterType<IMessageWriter, DebugMessageWriter>();
            
            var orderProcessor = container.Resolve<OrderProcessor>();
 
            orderProcessor.SubmitOrder();
        }
    }

 

That’s right – the only one called will be the DebugMessageWriter implementation! The last one registered wins.

Now let’s say you change your mind and decide to accept all the registered implementations of IMessageWriter:

    public class OrderProcessor
    {
        private readonly IMessageWriter[] _messageWriters;
 
        public OrderProcessor(IMessageWriter[] messageWriters)
        {
            _messageWriters = messageWriters;
        }
 
        public void SubmitOrder()
        {
            // do something special with the order
 
            foreach (var writer in _messageWriters)
                writer.Write("Submit order...");
 
            // do some more with the order
        }
    }

 

Which implementation will be used? Neither. How can you get the container to use your implementations? It ends up you have to give each registered implementation a unique name, like this:

    class Program
    {
        static void Main(string[] args)
        {
            var container = new UnityContainer();
 
            container.RegisterType<IMessageWriter, ConsoleMessageWriter>("console");
            container.RegisterType<IMessageWriter, DebugMessageWriter>("debug");
            
            var orderProcessor = container.Resolve<OrderProcessor>();
 
            orderProcessor.SubmitOrder();
        }
    }

 

Now when you run the code both implementations will be called. This was not really clear to me when I started working with Unity so I hope this clears up some fog for others.

Enjoy!

Posted on Monday, October 19, 2009 10:56 PM IoC , Unity | Back to top


Comments on this post: Injecting an array of objects with Unity

# re: Injecting an array of objects with Unity
Requesting Gravatar...
Thanks for posting. How did you find out about the requirement for the unique name?
Left by Ian on Aug 09, 2010 7:18 PM

Your comment:
 (will show your gravatar)


Copyright © Jon Dalberg | Powered by: GeeksWithBlogs.net