簡體   English   中英

帶有WEB.API和Castle Windsor容器的ASP.NET MVC

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM