【发布时间】: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