![](/img/trans.png)
[英]Castle Windsor ASP.NET MVC 4 and Web API same application. Only if MVC controllers have no dependencies?
[英]ASP.NET MVC with WEB.API and Castle Windsor container
我有帶有集成的Castle Windsor容器的ASP.NET MVC應用程序。 當我添加ApiController並嘗試執行POST時,出現錯誤消息:“確保控制器具有無參數的公共構造函數。” 感謝您的任何建議。
溫莎城堡一體化:
public class CastleControllerFactory : DefaultControllerFactory
{
public IWindsorContainer Container { get; protected set; }
public CastleControllerFactory(IWindsorContainer container)
{
if (container == null)
{
throw new ArgumentException("container");
}
this.Container = container;
}
protected override IController GetControllerInstance(RequestContext requestContext, Type controllerType)
{
if (controllerType == null)
{
return null;
}
return Container.Resolve(controllerType) as IController;
}
public override void ReleaseController(IController controller)
{
var disposableController = controller as IDisposable;
if (disposableController != null)
{
disposableController.Dispose();
}
Container.Release(controller);
}
}
public class DefaultCastleInstaller : IWindsorInstaller
{
public void Install(IWindsorContainer container, IConfigurationStore store)
{
container.AddFacility<TypedFactoryFacility>();
//Functions
//container.Register(Component.For<IGetIPAddressesFromRange>().ImplementedBy<GetIPAddressesFromRange>().LifestylePerWebRequest());
container.Register(Component.For<IUnitOfWork>().ImplementedBy<UnitOfWork>().LifestylePerWebRequest());
var contollers = Assembly.GetExecutingAssembly().GetTypes().Where(x => x.BaseType == typeof(Controller)).ToList();
foreach (var controller in contollers)
{
container.Register(Component.For(controller).LifestyleTransient());
}
var apiContollers = Assembly.GetExecutingAssembly().GetTypes().Where(x => x.BaseType == typeof(ApiController)).ToList();
foreach (var apiController in apiContollers)
{
container.Register(Component.For(apiController).LifestyleTransient());
}
}
}
public class MvcApplication : System.Web.HttpApplication
{
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
GlobalConfiguration.Configure(WebApiConfig.Register);
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
//Integrace CastleWindsor
var container = new WindsorContainer();
container.Install(new DefaultCastleInstaller());
var castleControllerFactory = new CastleControllerFactory(container);
ControllerBuilder.Current.SetControllerFactory(castleControllerFactory);
}
}
ApiController:
public class UserVerificationController : ApiController
{
private readonly IUnitOfWork _unitOfWork;
/// <summary>
/// Konstruktor
/// </summary>
/// <param name="unitOfWork"></param>
public UserVerificationController(IUnitOfWork unitOfWork)
{
_unitOfWork = unitOfWork;
}
// GET api/<controller>
public IEnumerable<string> Get()
{
return new string[] { "value1", "value2" };
}
}
問題在於,由於MVC和Web API控制器是單獨的實體,因此您都需要進行Windsor配置。 您已將Windsor配置為創建MVC控制器。 您只需要Web API控制器使用相同的控件即可。
這是一個Web API控制器激活器,大部分是從本博客文章中提煉出來的 。
public class WindsorWebApiControllerActivator : IHttpControllerActivator
{
private readonly IWindsorContainer _container;
public WindsorWebApiControllerActivator(IWindsorContainer container)
{
_container = container;
}
public IHttpController Create(
HttpRequestMessage request,
HttpControllerDescriptor controllerDescriptor,
Type controllerType)
{
var controller =
(IHttpController)this._container.Resolve(controllerType);
request.RegisterForDispose(
new Release(
() => this._container.Release(controller)));
return controller;
}
private class Release : IDisposable
{
private readonly Action _release;
public Release(Action release)
{
_release = release;
}
public void Dispose()
{
_release();
}
}
}
並且您需要在容器中注冊所有控制器類型。 這是注冊所有MVC 和 Web API控制器的IWindsorInstaller
:
public class ControllersInstaller : IWindsorInstaller
{
public void Install(IWindsorContainer container, IConfigurationStore store)
{
container.Register(
Classes.
FromThisAssembly().
BasedOn<IController>(). //MVC
If(c => c.Name.EndsWith("Controller")).
LifestyleTransient());
container.Register(
Classes.
FromThisAssembly().
BasedOn<IHttpController>(). //Web API
If(c => c.Name.EndsWith("Controller")).
LifestyleTransient());
}
}
然后在啟動時用您的默認Web API控制器激活器替換:
GlobalConfiguration.Configuration.Services.Replace(
typeof(IHttpControllerActivator),
new WindsorWebApiControllerActivator(container));
並確保致電安裝程序:
container.Install(new ControllersInstaller());
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.