Naz*_*Naz 9 c# asp.net castle-windsor asp.net-mvc-3 asp.net-web-api
我知道可以使用DependancyResolver并将Castle Windsor注册到MVC但是由于/sf/answers/342245571/中描述的问题,我们坚持使用我们的MVC项目上的WindsorControllerFactory实现方法.
然而,看起来ApiControllers正在使用其他类型的工厂,因为Castle Windsor无法注入依赖项.
有没有人想出如何使用Castle Windsor与ASP.NET Web API和MVC而不使用DependencyResolver?
感谢Critiano的帖子和一些在线搜索我设法让它在这里工作是其他任何有这个问题的代码.我已经习惯使用MVC3和ASP.NET Web Api Beta,但我认为同样的解决方案应该适用于MVC4.
首先,我创建了一个WindsorHttpControllerFactory,因为ApiControllers使用的工厂与MVC不同.
public class WindsorHttpControllerFactory : IHttpControllerFactory
{
private readonly IKernel kernel;
private readonly HttpConfiguration configuration;
public WindsorHttpControllerFactory(IKernel kernel, HttpConfiguration configuration)
{
this.kernel = kernel;
this.configuration = configuration;
}
public IHttpController CreateController(HttpControllerContext controllerContext, string controllerName)
{
if (controllerName == null)
{
throw new HttpException(404, string.Format("The controller for path '{0}' could not be found.", controllerContext.Request.RequestUri.AbsolutePath));
}
var controller = kernel.Resolve<IHttpController>(controllerName);
controllerContext.Controller = controller;
controllerContext.ControllerDescriptor = new HttpControllerDescriptor(configuration, controllerName, controller.GetType());
return controllerContext.Controller;
}
public void ReleaseController(IHttpController controller)
{
kernel.ReleaseComponent(controller);
}
}
Run Code Online (Sandbox Code Playgroud)
棘手的部分是注册它似乎涉及注册一大堆其他东西.这就是我最终的结果.
container.Register(Component.For<IHttpControllerFactory>().ImplementedBy<WindsorHttpControllerFactory>().LifeStyle.Singleton);
container.Register(Component.For<System.Web.Http.Common.ILogger>().ImplementedBy<MyLogger>().LifeStyle.Singleton);
container.Register(Component.For<IFormatterSelector>().ImplementedBy<FormatterSelector>().LifeStyle.Singleton);
container.Register(Component.For<IHttpControllerActivator>().ImplementedBy<DefaultHttpControllerActivator>().LifeStyle.Transient);
container.Register(Component.For<IHttpActionSelector>().ImplementedBy<ApiControllerActionSelector>().LifeStyle.Transient);
container.Register(Component.For<IActionValueBinder>().ImplementedBy<DefaultActionValueBinder>().LifeStyle.Transient);
container.Register(Component.For<IHttpActionInvoker>().ImplementedBy<ApiControllerActionInvoker>().LifeStyle.Transient);
container.Register(Component.For<System.Web.Http.Metadata.ModelMetadataProvider>().ImplementedBy<System.Web.Http.Metadata.Providers.CachedDataAnnotationsModelMetadataProvider>().LifeStyle.Transient);
container.Register(Component.For<HttpConfiguration>().Instance(configuration));
//Register all api controllers
container.Register(AllTypes.FromAssembly(assemblyToRegister)
.BasedOn<IHttpController>()
.Configure(registration => registration.Named(registration.ServiceType.Name.ToLower().Replace("controller", "")).LifeStyle.Transient));
//Register WindsorHttpControllerFactory with Service resolver
GlobalConfiguration.Configuration.ServiceResolver.SetService(typeof(IHttpControllerFactory), container.Resolve<IHttpControllerFactory>());
Run Code Online (Sandbox Code Playgroud)
我必须创建自己的ILogger实现,你可以使用像波纹管那样的存根版本.
public class MyLogger : System.Web.Http.Common.ILogger
{
public void LogException(string category, TraceLevel level, Exception exception)
{
// Do some logging here eg. you could use log4net
}
public void Log(string category, TraceLevel level, Func<string> messageCallback)
{
// Do some logging here eg. you could use log4net
}
}
Run Code Online (Sandbox Code Playgroud)