I’m working on a large Asp.Net MVC3 application (>50 views) and we are currently planning on using Unity for our dependency injection framework. For ease of maintenance, I would like to be able to query the assembly to find all of the base types, then register them with Unity.
Based on sample code from the Unity MVC3 Project for registering all controllers, I tried the following code –
var orchestratorTypes = (from t in Assembly.GetCallingAssembly().GetTypes()
where typeof(IOrchesratorBase).IsAssignableFrom(t) &&
!t.IsAbstract
select t).ToList();
orchestratorTypes.ForEach(t => container.RegisterType(t);
When I run the application I get the following error message
The current type, WwpMvcHelpers.BaseClasses.IOrchesratorBase, is an interface and cannot be constructed. Are you missing a type mapping?
If I register the class using individually, as below –
container.RegisterType<IOrchesratorBase, HomeOrchestrator>();
Everything works correctly. Is there a way to do this so that I don’t have to register each type individually?
EDIT
Per request, my inheritance hierarchy is
HomeOrcestrator <- IOrchesratorBaseList<LocalModel>
<- OrchesratorBase<LocalModel> <- IOrchesratorBase
The usage in the controller is
public class HomeController : ControllerListBase <HomeOrchestrator, LocalModel>
{
public HomeController() {}
public HomeController(IOrchesratorBase homeOrchestrator) {
this.Orchestrator = (HomeOrchestrator) homeOrchestrator;
}
The LINQ to get the types appears to work. I don’t think that’s your problem.
You’ll get a similar error if you just write
and call
container.Resolve<IOrchesratorBase>().In other words,
RegisterType(t)is not the same asRegisterType<I, T>().The real question is, what are you resolving and how do you want it resolved? Your query is finding implementors of IOrchesratorBase. Are your injection constructor parameters of that type? If so, what’s Unity supposed to do when 20 types implement that interface?
Can you provide more information on your class/interface hierarchy, constructor parameters, and what you expect/want to happen?
(I’d refactor to change IOrchesratorBase to IOrchestratorBase, BTW.) 🙂
Edit
Based on the edited question, the problem is that, in order to resolve a HomeController, Unity is looking for a type registration for IOrchesratorBase. It determines the interface type by the parameter types of the constructor with the most parameters.
If you write
container.RegisterType<IOrchesratorBase, HomeOrchestrator>()the answer is obvious – Unity will construct an instance of HomeOrchestrator and inject it.Now, is there more than one type that implements IOrchesratorBase? If so, and you register both of them (explicitly), Unity will use whichever one you register last. That may not be what you want.
If you have multiple controllers, each taking a different interface type in their constructors (with only one implementation per interface), you’ll need to figure out what each interface type is and re-run your LINQ registration for each one. That could be done via reflection – find the orchestrators or the controllers.
If you have multiple controllers, each taking the same interface type in their constructors and you want different implementations for each, you’ve got a problem. You’d have to register named types and determine the names somehow, or something similar.
Unity isn’t magic. It can’t figure out your intentions.
Addendum
Unity can operate in a convention-over-configuration mode; see Using Unity With Minimal Configuration.