pangabiMC pangabiMC - 1 year ago 76
C# Question

How to register a class that implements multiple interfaces in MVVM Light's SimpleIoc?

Let's say I have a couple of interfaces and a class that implements them:

public interface ISomething1 { /* blablabla */ }
public interface ISomething2 { /* blablabla */ }
public class Service : ISomething1, ISomething2 { /* blablabla x 2 */ }

I'd like to register the class in the SimpleIoc with both of these interfaces:

SimpleIoc.Default.Register<ISomething1, Service >();
SimpleIoc.Default.Register<ISomething2, Service >();

However the second line here throws an ArgumentException with the message:

An item with the same key has already been added.

I'd have thought that the key here is the interface itself, but apparently that's not the case. My idea was to use explicit keys however I'd like to get the instances via dependency injection, where the IoC can only work with keyless registries.

So how could I use SimpleIoc here without changing either of the interfaces or the implementation itself?

Answer Source

Looking at the source code here (SimpleIoc.cs on CodePlex) has revealed what the problem was. When using this overload of the register function:

public void Register<TInterface, TClass>(bool createInstanceImmediately)

as anticipated it will add TInterface and TClass to a dictionary where the interface is the key, however it also adds TClass and its constructor to another dictionary where the class is the key without any further checks.

I suspect it is a bug as if TClass was already known (ie. added to this constructor lookup map) it could simply live with that.


The solution / workaround is to use the factory type of registration. This works as expected:

SimpleIoc.Default.Register<ISomething1>(() => new Service());
SimpleIoc.Default.Register<ISomething2>(() => new Service());
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download