Hi Vasili,
Actually, you don't need to register each controller type in order to create it with the container. Here's how you can setup the container to dynamically create IController instances at runtime, based on the given controller name:
// Container setup code
Func<IFactoryRequest, IController> factoryMethod = request=>
{
var container = request.Container;
var controllerName = (string)request.Arguments[0];
// Note: This should work as long as you can acess the GetControllerType() method from the functor itself
var type = GetControllerType(controllerName);
return container.AutoCreate(type) as IController;
}
// Register the factory method to create IController instances
container.AddService<IController>(factoryMethod, LifecycleType.OncePerRequest);
...and here's the modified ControllerFactory class:
public class LinFuControllerFactory : DefaultControllerFactory
{
public override IController CreateController(
RequestContext
requestContext, string controllerName)
{
var type = GetControllerType(controllerName);
if (type == null)
{
throw new
InvalidOperationException(string.Format("Could not find a controller
with the name {0}", controllerName));
}
return container.GetService<IController>(controllerName);
}
protected virtual IServiceContainer GetContainer(RequestContext
context)
{
if (context == null)
{
throw new ArgumentNullException("context");
}
var application = context.HttpContext.ApplicationInstance
as LinFuHttpApplication;
if (application == null)
{
throw new InvalidOperationException("You must from
LinFuHttpApplication in your web project.");
}
var container = application.CurrentServiceContainer;
if (container == null)
{
throw new InvalidOperationException("The container
seems to be unavailable in your HttpApplication subclass");
}
return container;
}
At first, it might look the same as the old code, but what the factory method is actually doing is resolving your controller type at runtime and using AutoCreate to do the constructor injection. The difference is that every controller that is created out of that factory method will have property injection enabled, and that one call to AddService() effectively registers all your controller types within any given assembly, provided that you can resolve the controller type using the GetControllerType() method.
Hopefully, that should fix your issues with registration and property injection. Right now, I'm working on a patch that will let you do property injection on all types without having to register it in the container, and I'll let you know as soon as it's available. Anyway, try this out, and let me know if there's anything else I can do to help you.
Regards,
Philip Laureano