我正在讨论Sanderson的Pro ASP.NET MVC框架,在第4章他讨论了
Creating a Custom Controller Factory,看来用于注册控制器的原始方法AddComponentLifeStyle或AddComponentWithLifeStyle现在已被弃用:
- public class WindsorControllerFactory : DefaultControllerFactory
- {
- IWindsorContainer container;
- public WindsorControllerFactory()
- {
- container = new WindsorContainer(new XmlInterpreter(new ConfigResource("castle")));
- // register all the controller types as transient
- var controllerTypes = from t in Assembly.GetExecutingAssembly().GetTypes()
- where typeof(IController).IsAssignableFrom(t)
- select t;
- //[Obsolete("Use Register(Component.For<I>().ImplementedBy<T>().Named(key).Lifestyle.Is(lifestyle)) instead.")]
- //IWindsorContainer AddComponentLifeStyle<I,T>(string key,LifestyleType lifestyle) where T : class;
- foreach (Type t in controllerTypes)
- {
- container.Register(Component.For<IController>().ImplementedBy<???>().Named(t.FullName).LifeStyle.Is(LifestyleType.Transient));
- }
- }
- // Constructs the controller instance needed to service each request
- protected override IController GetControllerInstance(Type controllerType)
- {
- return (IController)container.Resolve(controllerType);
- }
- }
新的建议是使用Register(Component.For< I>().ImplementedBy< T>().Named(key).Lifestyle.Is(lifestyle)),但我无法弄清楚如何呈现实现控制器输入ImplementedBy< ???>()方法.我尝试了ImplementedBy< t>()和ImplementedBy< typeof(t)>(),但我找不到传递实现类型的适当方法.有任何想法吗?
解决方法
我正在使用
ControllerBuilder.SetControllerFactory
以及您可以在开源项目
MvcContrib中找到的代码执行此操作:
的Global.asax.cs
- protected void Application_Start()
- {
- ...
- IWindsorContainer windsorContainer = new WindsorContainer();
- windsorContainer.RegisterControllers(Assembly.GetExecutingAssembly());
- ControllerBuilder.Current.SetControllerFactory(new WindsorControllerFactory(windsorContainer));
- ...
- }
WindsorControllerFactory
- public class WindsorControllerFactory : DefaultControllerFactory
- {
- private readonly IWindsorContainer _container;
- public WindsorControllerFactory(IWindsorContainer container)
- {
- if (container == null)
- {
- throw new ArgumentNullException();
- }
- _container = container;
- }
- protected override IController GetControllerInstance(RequestContext requestContext,Type controllerType)
- {
- if (controllerType == null)
- {
- throw new HttpException();
- }
- if (!typeof(IController).IsAssignableFrom(controllerType))
- {
- throw new ArgumentException();
- }
- try
- {
- return (IController)_container.Resolve(controllerType);
- }
- catch (Exception ex)
- {
- throw new InvalidOperationException();
- }
- }
- public override void ReleaseController(IController controller)
- {
- IDisposable disposable = controller as IDisposable;
- if (disposable != null)
- {
- disposable.Dispose();
- }
- _container.Release(controller);
- }
- }
WindsorExtensions(见MvcContrib)
- public static class WindsorExtensions
- {
- public static IWindsorContainer RegisterController<T>(this IWindsorContainer container) where T : IController
- {
- container.RegisterControllers(typeof(T));
- return container;
- }
- public static IWindsorContainer RegisterControllers(this IWindsorContainer container,params Type[] controllerTypes)
- {
- foreach (Type type in controllerTypes)
- {
- if (ControllerExtensions.IsController(type))
- {
- container.Register(Component.For(type).Named(type.FullName).LifeStyle.Is(LifestyleType.Transient));
- }
- }
- return container;
- }
- public static IWindsorContainer RegisterControllers(this IWindsorContainer container,params Assembly[] assemblies)
- {
- foreach (Assembly assembly in assemblies)
- {
- container.RegisterControllers(assembly.GetExportedTypes());
- }
- return container;
- }
- }
ControllerExtensions(见MvcContrib)
- public static class ControllerExtensions
- {
- public static bool IsController(Type type)
- {
- return type != null
- && type.Name.EndsWith("Controller",StringComparison.OrdinalIgnoreCase)
- && !type.IsAbstract
- && typeof(IController).IsAssignableFrom(type);
- }
- }