Yes, you need to use reflection easily to create all the mappings you need. Since you are using Unity 3, you can use Convention Registration to provide assistance (with a more difficult upgrade) in registering classes.
I took your pseudo code and translated it into real code:
public abstract class BaseClass { public abstract void DoFoo(); } public class ClassNumber001 : BaseClass { public override void DoFoo() { Console.WriteLine("001 Foo"); } } public class ClassNumber002 : BaseClass { public override void DoFoo() { Console.WriteLine("002 Foo"); } } public interface ISuperman { void Do(); } public class Superman<T> : ISuperman where T : BaseClass { private T baseClass; public Superman(T baseClass) { this.baseClass = baseClass; } public void Do() { this.baseClass.DoFoo(); } } public class MainViewModel { public MainViewModel(IEnumerable<ISuperman> lotsofSuperman) { foreach(ISuperman superman in lotsofSuperman) { superman.Do(); } } }
Then use registration by convention to register all generics:
IUnityContainer container = new UnityContainer(); container.RegisterTypes( AllClasses.FromAssembliesInBasePath().Where(t => typeof(BaseClass).IsAssignableFrom(t)) .Select(t => typeof(Superman<>).MakeGenericType(t)), t => new Type[] { typeof(ISuperman) }, t => t.GetGenericArguments().First().Name, WithLifetime.Transient); container.RegisterType<IEnumerable<ISuperman>, ISuperman[]>(); container.Resolve<MainViewModel>();
In the above code, we get all the classes that inherit from BaseClass , and then create the Superman<> type and map it to ISuperman using the name BaseClass . Calling RegisterTypes will be equivalent to calling RegisterType for each BaseClass:
container.RegisterType<ISuperman, Superman<ClassNumber001>("ClassNumber001"); container.RegisterType<ISuperman, Superman<ClassNumber002>("ClassNumber002");
Then, when the MainViewModel resolves, MainViewModel through all the ISuperman instances and calls the method that prints:
001 foo
002 Foo
showing that we introduced 2 ISuperman instances: Superman<ClassNumber001> and Superman<ClassNumber002> .
If you need specific registrations for BaseClasses (for example, a non-default time manager), you can use registration by agreement to register them).