asp.net mvc - How to use Dependency Injection with a Controller -


i have below code work without issue mausercontroller.cs

public class mausercontroller : apicontroller     {         ilogservice loggerservice;         imauserservice _service;          public mausercontroller(ilogservice loggerservice, imauserservice service)         {             this.loggerservice = loggerservice;             this._service = service;         } } 

dependencyinstaller.cs

public class dependencyinstaller : iwindsorinstaller     {         public void install(iwindsorcontainer container, iconfigurationstore store)         {             container.register(                 component.for<ilogservice>().implementedby<logservice>().lifestyle.perwebrequest,                 component.for<idatabasefactory>().implementedby<databasefactory>().lifestyle.perwebrequest,                 component.for<iunitofwork>().implementedby<unitofwork>().lifestyle.perwebrequest,                 alltypes.fromthisassembly().basedon<ihttpcontroller>().lifestyletransient(),                 alltypes.fromassemblynamed("isos.health.service").where(type => type.name.endswith("service")).withserviceallinterfaces().lifestyleperwebrequest(),                 alltypes.fromassemblynamed("isos.health.repository").where(type => type.name.endswith("repository")).withserviceallinterfaces().lifestyleperwebrequest()                                );         }     } 

if using normal controller instead apicontroller gives me error usercontroller.cs

public class usercontroller : controller     {         ilogservice loggerservice;         imauserservice _service;         public usercontroller(ilogservice loggerservice, imauserservice service)         {             this.loggerservice = loggerservice;             this._service = service;         } } 

this give error:

no parameterless constructor defined object

i using castledi windsor dependency injection.

do need or register something?

first approach

advice: use caution, because may cause memory leaks castle windsor.

you have create controller activator, should implement icontrolleractivator interface, in order use di container create controller instances:

public class mywindsorcontrolleractivator : icontrolleractivator {     public mywindsorcontrolleractivator(iwindsorcontainer container)     {         _container = container;     }      private iwindsorcontainer _container;      public icontroller create(requestcontext requestcontext, type controllertype)     {         return _container.resolve(controllertype) icontroller;     } } 

then, add class dependencyinstaller:

public class dependencyinstaller : iwindsorinstaller {     public void install(iwindsorcontainer container, iconfigurationstore store)     {         container.register(                 // current code...                  component.for<icontrolleractivator>()                     .implementedby<mywindsorcontrolleractivator>()                     .dependson(dependency.onvalue("container", container))                     .lifestylesingleton();             );     } } 

also, create own dependency resolver based on windsor container:

public class mywindsordependencyresolver : idependencyresolver {     public mywindsordependencyresolver(iwindsorcontainer container)     {         _container = container;     }      private iwindsorcontainer _container;      public object getservice(type servicetype)     {         return _container.resolve(servicetype);     }      public ienumerable<object> getservices(type servicetype)     {         return _container.resolveall(servicetype).cast<object>();     } } 

then, finally, register dependency resolver in application_start method in global.asax.cs:

dependencyresolver.setresolver(new mywindsordependencyresolver(windsorcontainer)); 

this way, when mvc requires controller activator through it's dependency resolver, ours, use our windsor container create controllers it's dependencies.

in order avoid memory leaks using icontrolleractivator, easiest solution use lifestyles per thread or per web request, rather default (singleton), transient , pooled, registered components. check this link more info how avoid memory leaks using castle windsor container.

second approach

however, pointed out @phildegenhardt, better , correct approach implement custom controller factory, in order able release controller component created castle windsor di container. here can find example (see section dependency injection).

taken example, implementation be:

global.asax.cs:

public class mvcapplication : system.web.httpapplication {     private windsorcontainer _windsorcontainer;      protected void application_start()     {         var _windsorcontainer = new windsorcontainer();         _windsorcontainer.install(             new dependencyinstaller(),             // other installers...         );          controllerbuilder.current.setcontrollerfactory(new windsorcontrollerfactory(_windsorcontainer.kernel));     }      protected void application_end()     {         if (_windsorcontainer != null)         {             _windsorcontainer.dispose();         }     } } 

windsorcontrollerfactory.cs:

public class windsorcontrollerfactory : defaultcontrollerfactory {     private readonly ikernel _kernel;      public windsorcontrollerfactory(ikernel kernel)     {         _kernel = kernel;     }      public override void releasecontroller(icontroller controller)     {         _kernel.releasecomponent(controller);  // important part: release component     }      protected override icontroller getcontrollerinstance(requestcontext requestcontext, type controllertype)     {         if (controllertype == null)         {             throw new httpexception(404, string.format("the controller path '{0}' not found.", requestcontext.httpcontext.request.path));         }         return (icontroller)_kernel.resolve(controllertype);     } } 

Comments

Popular posts from this blog

c++ - Difference between pre and post decrement in recursive function argument -

php - Nothing but 'run(); ' when browsing to my local project, how do I fix this? -

php - How can I echo out this array? -