c# - ASP.NET MVC with WEB.API and Castle Windsor container -
i have asp.net mvc application integrated castle windsor container. when added apicontroller, , tried post, got error message: "make sure controller has parameterless public constructor." advice.
castle windsor integration:
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) icontroller; } public override void releasecontroller(icontroller controller) { var disposablecontroller = controller 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; } // api/<controller> public ienumerable<string> get() { return new string[] { "value1", "value2" }; } }
the problem because mvc , web api controllers separate entities, need windsor configuration both. you've got windsor configured create mvc controllers. need same web api controllers.
here's web api controller activator, lifted 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(); } } }
and need register of controller types container. here's iwindsorinstaller
registers mvc and web api controllers:
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()); } }
then @ startup replace default web api controller activator yours:
globalconfiguration.configuration.services.replace( typeof(ihttpcontrolleractivator), new windsorwebapicontrolleractivator(container));
and sure call installer:
container.install(new controllersinstaller());
Comments
Post a Comment