c# - Inject dependency with "constructor scope" - autofac -


i using autofac 3.5.x , have setup similar this:

public class servicea : iservicea { } public class serviceb : iserviceb { public serviceb(iservicea sa) { } } public class servicec : iservicec { public servicec(iservicea sa) { } } public class serviced : iserviced { public serviced(iservicea sa, iserviceb sb, iservicec sc) {} } 

in container have following registrations:

builder.registertype<servicea>.as<iservicea>(); builder.registertype<serviceb>.as<iserviceb>(); builder.registertype<servicec>.as<iservicec>(); builder.registertype<serviced>.as<iserviced>(); 

here want: when request new iserviced container, want same iservicea instance injected iserviced , dependencies iserviceb , iservicec. not looking global singleton scope though. next time ask iserviced instance must created new instance of iservicea (i know cannot create instance of interface, think point).

to illustrate; when ask autofac container iserviced want following happen:

public class serviced : iserviced {     public serviced(iservicea sa, iserviceb sb, iservicec sc)     {         // sa should same (but not)         sa.gethashcode() == sb.getservicea().gethashcode() == sc.getservicea().gethashcode()     } } 

please note getservicea() method included illustrate point.

so yeah, guess looking way tell autofac when resolves iserviced should create singleton of servicea scope of serviced's constructor.

right now, use autofacs support delegate factories, , ask for:

public serviced(iservicea sa, func<iservicea, iserviceb> fb, func<iservicea, iservicec> fc) : iserviced {      var sb = fb(sa); // manually inject same instance of servicea      var sc = fc(sa); // manually inject same instance of servicea       // servicea same instance      sa.gethashcode() == sb.getservicea().gethashcode() == sc.getservicea().gethashcode() } 

this gets me going, have feeling can done better - why turning experts now.

thanks in advance.

the instanceperlifetimescope may suit need. allows have single instance per lifetime scope.

builder.registertype<servicea>().as<iservicea>().instanceperlifetimescope(); builder.registertype<serviceb>().as<iserviceb>().instanceperlifetimescope(); builder.registertype<servicec>().as<iservicec>().instanceperlifetimescope(); builder.registertype<serviced>().as<iserviced>().instanceperlifetimescope(); 

then, each time resolve iserviced in new scope have single instance of iservicea

using (ilifetimescope scope = container.beginlifetimescope()) {     // instance of iservicea created scope     scope.resolve<iserviced>();  } 

if can't create new ilifetimescope can use owned<t> type lightweight lifetimescope.

using (owned<iserviced> ownedd = container.resolve<owned<iserviced>>()) {     iserviced serviced = ownedd.value;                  } 

each time resolve owned<iserviced> new ilifetimescope created , single iservicea created.

if not enough can play instancepermatchinglifetimescope make code , registration quite difficult read , debug. instanceperlifetimescope should enough.

another solution use kind of registration.

builder.register(ctx => {     iservicea servicea = ctx.resolve<iservicea>();     iserviceb serviceb = ctx.resolve<iserviceb>(typedparameter.from(servicea));     iservicec servicec = ctx.resolve<iservicec>(typedparameter.from(servicea));     iserviced serviced = ctx.resolve<iserviced>(typedparameter.from(servicea), typedparameter.from(serviceb), typedparameter.from(servicec));     return serviced; }).as<iserviced>(); 

but not elegant.


Comments

Popular posts from this blog

twig - Using Twigbridge in a Laravel 5.1 Package -

jdbc - Not able to establish database connection in eclipse -

firemonkey - How do I make a beep sound in Android using Delphi and the API? -