c# - Autofac register nested type? -
lets have these 4 types (with constructors).
public class mydbcontext : idatacontextasync { public class mydatacontext() { } } public class unitofwork : iunitofworkasync { public unitofwork(idatacontextasync datacontext) { _datacontext = datacontext; } } public class repository<tentity> : irepositoryasync<tentity> { public repository(idatacontextasync context, iunitofworkasync unitofwork) { _context = context; _unitofwork = unitofwork; } } public class accountservice : iaccountservice { private readonly iunitofworkasync _uow; private readonly irepositoryasync<account> _repository; public accountservice(iunitofworkasync uow, irepositoryasync<account> repository) { _uow = uow; _repository = repository; } }
i try register them in container (i'm using wcf way).
var builder = new containerbuilder(); builder.registertype<mydbcontext>().as<idatacontextasync>(); builder.registertype<unitofwork>().as<iunitofworkasync>(); builder.registergeneric(typeof(repository<>)).as(typeof(irepositoryasync<>)); builder.registerassemblytypes(typeof(accountservice).assembly) .where(t => t.name.endswith("service")) .as(t => t.getinterfaces().firstordefault( => i.name == "i" + t.name)); container = builder.build();
it seems container generated instance of unitofwork injected accountservice different unitofwork instance created when repository instantiated container. how ensure repository gets instantiated same instance? example, here how objects instantiated without container.
var context = new mydbcontext(); _uow = new unitofwork(context); _repository = new repository<account>(context, _uow); accountservice service = new accountservice(_uow, _repository);
as can see, _uow
, , _uow
parameter repository created same instance. not case when autofac instantiates objects , can't seem figure out how "tie them together".
by default autofac scope per dependency. means each time autofac need resolve dependency, return new instance.
if want have common instance per lifetime or request, have register type using appropriate scope.
var builder = new containerbuilder(); builder.registertype<mydbcontext>() .as<idatacontextasync>() .instanceperlifetimescope(); builder.registertype<unitofwork>() .as<iunitofworkasync>() .instanceperlifetimescope(); builder.registergeneric(typeof(repository<>)) .as(typeof(irepositoryasync<>)) .instanceperlifetimescope(); builder.registerassemblytypes(typeof(accountservice).assembly) .where(t => t.name.endswith("service")) .as(t => t.getinterfaces().firstordefault(i => i.name == "i" + t.name)) .instanceperlifetimescope(); container = builder.build();
see instance scope in autofac documentation more information.
by way, autofac integration wcf seems not support per-request lifetimescope
due wcf internals, there no explicit support in wcf per-request lifetime dependencies.
this limitation related fact wcf has own instance scope. recommended use instancecontextmode.percall
sure wcf ask new instance of service each wcf call. can use servicebehavior
attribute
[servicebehavior(instancecontextmode = instancecontextmode.percall)] public class myservice : imyservice { }
i read source code of autofacinstancecontext.cs , seems new lifetimescope created each wcf call. can register dependency instanceperlifetimescope
, should work.
Comments
Post a Comment