2016-07-25 4 views
0

Castle Windsorコンテナを統合したASP.NET MVCアプリケーションがあります。私がApiControllerを追加してPOSTをしようとすると、エラーメッセージが表示されます。「コントローラーにパラメータのないpublicコンストラクターがあることを確認してください」アドバイスありがとう。WEB.APIとCastle Windsorコンテナを持つASP.NET MVC

城ウィンザーの統合:

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" }; 
    } 
} 

答えて

0

問題はMVCとWeb APIコントローラは別々のエンティティであるため、あなたは両方のためのウィンザーの設定を必要とするということです。 WindsorがMVCコントローラを作成するように設定されています。 Web APIコントローラーには同じものが必要です。

Web APIコントローラアクティベータは、ほとんどがthis blog postから削除されています。

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(); 
     } 
    } 
} 

そして、すべてのコントローラタイプをコンテナに登録する必要があります。

GlobalConfiguration.Configuration.Services.Replace(
    typeof(IHttpControllerActivator), 
    new WindsorWebApiControllerActivator(container)); 

をし、インストーラを呼び出してください:

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コントローラー活性化因子を置き換えます。ここでは、すべてのMVC ウェブAPIコントローラを登録IWindsorInstaller

container.Install(new ControllersInstaller()); 
関連する問題