【问题标题】:ASP.NET MVC - setting custom IControllerFactory has no effectASP.NET MVC - 设置自定义 IControllerFactory 无效
【发布时间】:2013-11-03 05:42:16
【问题描述】:

我真的不明白我在这里做错了什么 - 由于某种原因,IControllerFactory i 寄存器没有被使用,我最终得到一个 System.ArgumentException

Type 'Company.WebApi.Controllers.AController' 没有默认值 构造函数

在 System.Linq.Expressions.Expression.New(Type type) 在 System.Web.Http.Internal.TypeActivator.Create[TBase](类型 实例类型)在 System.Web.Http.Dispatcher.DefaultHttpControllerActivator.GetInstanceOrActivator(HttpRequestMessage 请求,类型控制器类型,Func`1& 激活器)在 System.Web.Http.Dispatcher.DefaultHttpControllerActivator.Create(HttpRequestMessage 请求,HttpControllerDescriptor 控制器描述符,类型 控制器类型)

在 Global.asax.cs 中

protected void Application_Start()
{
    //DI-setup
    var container = new WindsorContainer().Install(new WebWindsorInstaller());

    //set custom controller factory
    var controllerFactory = container.Resolve<IControllerFactory>();
    ControllerBuilder.Current.SetControllerFactory(controllerFactory);

    //register cors
    container.Resolve<ICorsConfig>().RegisterCors(GlobalConfiguration.Configuration);

    //routes
    RegisterRoutes(RouteTable.Routes);
}

我的IControllerFactory是基于这篇文章http://keyvan.io/custom-controller-factory-in-asp-net-mvc,实现如下

public class ControllerFactory : IControllerFactory
    {
        private readonly IWindsorContainer _container;

        public ControllerFactory(IWindsorContainer container)
        {
            if(container == null)
                throw new ArgumentNullException("container");

            _container = container;
        }

        public IController CreateController(RequestContext requestContext, string controllerName)
        {
            if (string.IsNullOrEmpty(controllerName))
                throw new ArgumentNullException("controllerName");

            var componentName = GetComponentNameFromControllerName(controllerName);

            return _container.Resolve<IController>(componentName);
        }

        public SessionStateBehavior GetControllerSessionBehavior(RequestContext requestContext, string controllerName)
        {
            throw new NotImplementedException();
        }

        public void ReleaseController(IController controller)
        {
            _container.Release(controller);
        }

        static string GetComponentNameFromControllerName(string controllerName)
        {
            var controllerNamespace = typeof (CrudController<>).Namespace;
            return string.Format("{0}.{1}Controller", controllerNamespace, controllerName);
        }
    }

我已经盯着这个看了好几个小时,真的不明白为什么这不起作用。在调试 ControllerFactory 时,除了构造函数之外的任何方法都不会被命中。有人看到这里有什么问题或遗漏吗?

Setting ASP.NET MVC ControllerFactory has no effect 没有回答我的问题)

编辑 1 - 控制器

    public class AController : CrudController<AModel>
    {
        public AController(IAHandler aHandler) : base(aHandler)
        {
            ...
        }

        [HttpGet]
        public HttpResponseMessage GetByUser(string aId)
        {
            ...
        }
    }

    public abstract class CrudController<T> : ApiController
        where T : IModel, new()
    {
        protected CrudController(ICrudHandler<T> handler)
        {
            ...
        }

        [HttpGet]
        public HttpResponseMessage Get(string id)
        {
            ...
        }

        [HttpPost]
        public HttpResponseMessage Post(T input)
        {
            ...
        }

        [HttpPut]
        public HttpResponseMessage Put(T input)
        {
            ...
        }
    }

编辑 2 - 安装程序

    public sealed class WebWindsorInstaller : IWindsorInstaller
    {
        private bool _installComplete;

        public void Install(IWindsorContainer container, IConfigurationStore store)
        {
            if(_installComplete)
                return;

            //register self for reuse
            container.Register(Component.For<IWindsorInstaller>().Instance(this));

            //controller factory
            container.Register(
                Component.For<IControllerFactory>().ImplementedBy<ControllerFactory>().LifeStyle.Singleton);

            //Handlers
            container.Register(
                Classes.FromAssemblyContaining<AHandler>().InSameNamespaceAs<AHandler>().WithService.
                    DefaultInterfaces());

            //Models
            container.Register(
                Classes.FromAssemblyContaining<AModel>().InSameNamespaceAs<AModel>().WithService.Self());

            //DI
            container.Register(Component.For<IWindsorContainer>().Instance(container));
            container.Register(Component.For<IDependencyResolver>().ImplementedBy<WindsorDependencyResolver>());

            //Controllers
            container.Register(Classes
                .FromAssemblyContaining<AController>()
                .BasedOn<IHttpController>()
                .LifestyleScoped());

            //repositories
            container.Register(
                Classes.FromAssemblyContaining<ARepository>().InSameNamespaceAs<ARepository>().WithService.
                    DefaultInterfaces());

            //cors
            container.Register(Component.For<ICorsConfig>().ImplementedBy<CorsConfig>());

            _installComplete = true;
        }
    }

【问题讨论】:

  • 你在哪里注册ControllerFactory类型的容器?
  • 我刚刚查看了您在问题中提供的链接。在链接中,自定义控制器工厂设置在这一行ControllerBuilder.Current.SetControllerFactory(typeof(CustomControllerFactory));。您正在尝试使用容器解析 IControllerFactory 实例,但没有先向容器注册任何内容(除非您错过了一些细节)
  • 嗨,Suhas,感谢您的关注。一切都在var container = new WindsorContainer().Install(new WebWindsorInstaller());行中注册了正如我提到的ControllerFactory的构造函数在调试时被命中,证明解析正确执行
  • 你能展示你的控制器类抛出这个异常吗?
  • 你在哪里将 IControllerFactory 映射到它对应的 impl (ControllerFactory)?我现在不关心温莎,它会自动解决吗?

标签: asp.net-mvc


【解决方案1】:

从您问题中的错误消息看来,您实际上想要注册 WebAPI 控制器。请务必注意,这些与 MVC 控制器不同,并且不要使用相同的控制器工厂(您正在尝试使用)。

有关如何为 Web API 控制器执行此操作的详细信息,请参阅 Mark Seeman 的帖子 Dependency Injection in ASP.NET Web API with Castle Windsor

【讨论】:

    猜你喜欢
    • 2010-11-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多