tags:

views:

70

answers:

2

I'm using UnityContainer, and I want to register an interface not with a type, but with another interface. Unfortunately, I'm unable to do it cleanly..

I have several common interfaces, which are united in one interface, and I need to register them in the container. The code is like the following:

interface IDeviceImporter {
    void ImportFromDevice();
}

interface IFileImporter {
    void ImportFromFile();
}

interface IImporter : IDeviceImporter, IFileImporter {
}


class Importer1: IImporter {
}
class Importer2: IImporter {
}

When entering the library, I know which importer to use, so the code is like:

var container = new UnityContainer();
if (useFirstImport) {
    container.RegisterType<IImporter, Importer1>();
} else {
    container.RegisterType<IImporter, Importer2>();
}

and then I want to register this specific class with IDeviceImporter and IFileImporter also. I need something like:

container.RegisterType<IDeviceImporter, IImporter>();

But with that code I'm getting an error: IImporter is an interface and cannot be constructed.

I can do it inside the condition, but then it'll be copy-paste. I can do

container.RegisterInstance<IDeviceImporter>(container.Resolve<IImporter>());

but it's really dirty. Anyone please, advice me something :)

+2  A: 

Well this is depends on your lifeteme management. Here

  container.RegisterType<IImporter, Importer1>();

you use transient one, so you can do following

var container = new UnityContainer();

if (useFirstImport) {
    container.RegisterType<IImporter, Importer1>();
    container.RegisterType<IDeviceImporter, Importer1>();

} else {
    container.RegisterType<IImporter, Importer2>();
    container.RegisterType<IDeviceImporter, Importer2>();
}

with no affraid of some tricky bugs. container.Resolve<IImporter>() will create new instance on every call, just like container.Resolve<IDeviceImporter>() will.

But if you are using ContainerControlledLifetimeManager then anyway you'll have to use container.RegisterInstance<IDeviceImporter>(container.Resolve<IImporter>()); becouse there is no other way in unity to do this.

This feature is realy interesting, it would be very nice to have something like container.CreateSymLink<IDeviceImporter, IImporter>(), but there is no such a thing.

er-v
A: 

I'm using ContainerControlledLifetimeManager, and end up with a code like:

var container = new UnityContainer();
System.Type importerType
if (useFirstImport) {
    importerType = GetType(Importer1);
} else {
    importerType = GetType(Importer2);
}

container.RegisterType(GetType(IImporter), importerType);
container.RegisterType(GetType(IDeviceImporter), importerType);
container.RegisterType(GetType(IFileImporter), importerType);

But yes, the best thing would be to have something like:

container.CreateSymLink<IDeviceImporter, IImporter>()
Shaddix