c# - conditional component registration in autofac -


is possible register component conditionally on other component's state? like:

containerbuilder.registerconditionally<t>(   func<icomponentcontext, bool>,    func<icomponentcontext, t>); 

i've found prior v2 of autofac 1 use "register().onlyif()" construction seemed 1 i'm looking for. such feature conditionally override default registration.

class commonregistrations {   public virtual void register(containderbuilder builder)   {     builder.register(ctx => loadsettings()).as<isettings>().singleinstance();     builder.registertype<defaultfoo>().as<ifoo>();   } }  class specificregistrations : commonregistrations {   public virtual void register(containerbuilder builder)   {     base.register(builder);     builder.conditionalyregister(       ctx => ctx.resolve<isettings>().reallyusespecificfoo,        ctx => new specificfoo()).as<ifoo>();   } }  ...  var builder = new containerbuilder(); var registrations = new specificregistrations(); registrations.register(builder); var container = builder.build(); ifoo foo = container.resolve<ifoo>(); 

the foo according isettings.reallyusespecificfoo either instance of defaultfoo or instance of specificfoo.

thank you.

there no way perform conditional registration @ container level based on container contents. trouble need resolve in container in order determine gets registered in container, technically affect whether wanted register thing in first place. chicken/egg circular dependency problem.

you can, however, register things conditionally nested lifetime scopes. integration points (like asp.net) resolve out of nested lifetime scopes (like http-request-length lifetime scope). can register things on fly nested lifetime scopes , might solve problem.

var builder = new containerbuilder(); builder.register(ctx => loadsettings()).as<isettings>().singleinstance(); builder.registertype<defaultfoo>().as<ifoo>(); var container = builder.build();  var settings = container.resolve<isettings>(); using(var scope =   container.beginlifetimescope(b => {     if(settings.reallyusespecificfoo)     {       b.registertype<specificfoo>().as<ifoo>();     }   }) {   // resolve things nested lifetime scope -   // use overrides. specificfoo if   // configuration setting true.   var foo = scope.resolve<ifoo>(); } 

another option have make registration lambda. might make registration more complex it's option consider.

var builder = new containerbuilder(); builder.register(ctx => {     var settings = ctx.resolve<isettings>();     if(settings.reallyusespecificfoo)     {       return new specificfoo();     }     return new defaultfoo();   }).as<ifoo>(); 

if manual construction there isn't appealing, pass through autofac, too.

var builder = new containerbuilder(); // register ifoo types - not "as<ifoo>" builder.registertype<defaultfoo>(); builder.registertype<specificfoo>(); // in lambda use resolve<t> instances. builder.register(ctx => {     var settings = ctx.resolve<isettings>();     if(settings.reallyusespecificfoo)     {       return ctx.resolve<specificfoo>();     }     return ctx.resolve<defaultfoo>();   }).as<ifoo>(); 

yet option update existing container after being built. in case, avoid chicken/egg scenario building container, using it, , changing registrations after fact.

var builder = new containerbuilder(); builder.register(ctx => loadsettings()).as<isettings>().singleinstance(); builder.registertype<defaultfoo>().as<ifoo>(); var container = builder.build();  var settings = container.resolve<isettings>(); if(settings.reallyusespecificfoo) {   var updater = new containerbuilder();   updater.registertype<specificfoo>().as<ifoo>();   updater.update(container); } 

finally, might consider xml configuration. given registration dependent on sort of configuration setting, might consider using autofac's xml configuration support. way, instead of trying resolve out of un-built container conditionally register else, specify right thing register using xml configuration , register correct thing first time.


Comments

Popular posts from this blog

c# - How Configure Devart dotConnect for SQLite Code First? -

java - Copying object fields -

c++ - Clear the memory after returning a vector in a function -