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
Post a Comment