entity framework - Autofac using Constructor -
i use unit of work pattern entityframework code first. want use autofac register unitofwork, repositories , dbcontext.
this unitofwork
code:
public class unitofwork : iunitofwork { private readonly dbcontext _context; public unitofwork(dbcontext context) { _context = context; contact = new contractrepository(context); } public void dispose() { _context.dispose(); gc.suppressfinalize(_context); } public icontactrepository contact { get; private set; } public int complete() { return _context.savechanges(); } }
and repository:
public class repository<entity> : irepository<entity> entity : class { protected readonly dbcontext _notebookcontext; public repository(dbcontext notebookcontext) { _notebookcontext = notebookcontext; } public void add(entity entity) { _notebookcontext.set<entity>().add(entity); } }
and 1 of repositories:
public class contractrepository: repository<contact>,icontactrepository { public contractrepository(dbcontext notebookcontext) : base(notebookcontext) { } public dbcontext notebookcontext { { return _notebookcontext; } } }
and db context class:
public class notebookcontext:dbcontext { public notebookcontext(string connectionstring):base(connectionstring) { } protected override void onmodelcreating(dbmodelbuilder modelbuilder) { modelbuilder.configurations.add(new contactconfig()); modelbuilder.configurations.add(new phoneconfig()); modelbuilder.configurations.add(new phonetypeconfig()); modelbuilder.configurations.add(new groupconfig()); base.onmodelcreating(modelbuilder); } public dbset<contact> contacts { get; set; } public dbset<phone> phones { get; set; } public dbset<group> groups { get; set; } public dbset<phonetype> phonetypes { get; set; } }
now want register unitofwork constructor (a constructor this: )
var uow = new unitofwork(new notebookdbcontext("connectionstring"));
note notebookcontext entity framework model.
i write registration got error:
var builder = new containerbuilder(); builder.registertype<notebookcontext>() .as<dbcontext>(); builder.registertype<unitofwork>() .usingconstructor(typeof(dbcontext)) .as<iunitofwork>(); builder.registergeneric(typeof(repository<>)) .as(typeof(irepository<>)) .instanceperlifetimescope(); container container = builder.build();
this error:
an unhandled exception of type 'autofac.core.dependencyresolutionexception' occurred in autofac.dll additional information: none of constructors found 'autofac.core.activators.reflection.defaultconstructorfinder' on type 'datalayer.notebookcontext' can invoked available services , parameters:
cannot resolve parameter 'system.string connectionstring' of constructor 'void .ctor(system.string)'.
edit 2 :
after cyril durand's answer write following registering config:
var builder = new containerbuilder(); builder.registertype<connectionstringprovider>().as<iconnectionstringprovider>(); builder.registertype<notebookcontext>().as<dbcontext>().withparameter((pi, c) => pi.name == "connectionstring", (pi, c) => c.resolve<iconnectionstringprovider>().connectionstring); builder.registertype<unitofwork>().as<iunitofwork>().withparameter(resolvedparameter.fornamed<dbcontext>("connectionstring")); builder.registergeneric(typeof(repository<>)).as(typeof(irepository<>)).instanceperlifetimescope();
and in code :
using (var scope = dependencyinjection.container.beginlifetimescope()) { var connectionstring = scope.resolve<iconnectionstringprovider>(); connectionstring.connectionstring = "context"; var uw = scope.resolve<iunitofwork>(); var =uw.contact.getall(); }
but got error again:
an unhandled exception of type 'autofac.core.dependencyresolutionexception' occurred in autofac.dll
additional information: exception thrown while invoking constructor 'void .ctor(system.string)' on type 'notebookcontext'.
can me?
the error message :
an unhandled exception of type
autofac.core.dependencyresolutionexception
occurred in autofac.dll additional information: none of constructors foundautofac.core.activators.reflection.defaultconstructorfinder
on typedatalayer.notebookcontext
can invoked available services , parameters:cannot resolve parameter
system.string connectionstring
of constructorvoid .ctor(system.string)
.
tells autofac can't create notebookcontext
because can resolve parameter named connectionstring
of type string
.
your notebookcontext
implementation needs connectionstring, autofac can't know without telling it. when register notebookcontext
have specify connectionstring :
builder.registertype<notebookcontext>() .as<dbcontext>() .withparameter("connectionstring", "xxx");
another solution dynamic resolution , iconnectionstringprovider
interface :
public interface iconnectionstringprovider { public string connectionstring { get; } }
and registration :
builder.registertype<connectionstringprovider>() .as<iconnectionstringprovider>() .instanceperlifetimescope(); builder.registertype<notebookcontext>() .as<dbcontext>() .withparameter((pi, c) => pi.name == "connectionstring", (pi, c) => c.resolve<iconnectionstringprovider>().connectionstring) .instanceperlifetimescope();
Comments
Post a Comment