c# - Multiple DbContexts in N-Tier Application -



c# - Multiple DbContexts in N-Tier Application -

i'm creating first n-tier mvc application , i've run road block how manage multiple dbcontexts database first approach.

i have next layers

presentation service (wcf) business info access

i don't want entity framework reference in service layer don't see how create interface or manage 2 contexts. have working single context warpped in idatabasefactory can't seem find approach manage two.

below unitofwork created in service ctor every way @ i'm still tied sitemodelcontainer, when in fact have context.

public class unitofwork : iunitofwork { private sitemodelcontainer _context; private readonly idatabasefactory _databasefactory; protected sitemodelcontainer sitecontext { { homecoming _context ?? (_context = _databasefactory.get()); } } public unitofwork(idatabasefactory factory) { _databasefactory = factory; _context = _databasefactory.get(); } //more code } public class databasefactory : disposable, idatabasefactory { private sitemodelcontainer _datacontext; public sitemodelcontainer get() { homecoming _datacontext ?? (_datacontext = new sitemodelcontainer()); } protected override void disposecore() { if (_datacontext != null) _datacontext.dispose(); } }

giving mill , unitofwork generic type parameter might solution:

public class unitofwork<t> : iunitofwork<t> t : dbcontext, new() { private t _context; private readonly idatabasefactory<t> _databasefactory; protected t context { { homecoming _context ?? (_context = _databasefactory.get()); } } public unitofwork(idatabasefactory<t> factory) { _databasefactory = factory; _context = _databasefactory.get(); } //more code } public class databasefactory<t> : disposable, idatabasefactory<t> t : dbcontext, new() { private t _datacontext; public t get() { homecoming _datacontext ?? (_datacontext = new t()); } protected override void disposecore() { if (_datacontext != null) _datacontext.dispose(); } }

the idatabasefactory , iunitwork interfaces have generic then.

you create unit of works different contexts:

var factory1 = new databasefactory<sitemodelcontainer>(); var unitofwork1 = new unitofwork<sitemodelcontainer>(factory1); var factory2 = new databasefactory<anothermodelcontainer>(); var unitofwork2 = new unitofwork<anothermodelcontainer>(factory2);

edit:

to rid of dependency on ef in service classes seek this. service knows these 3 interfaces:

public interface iunitofworkfactory { iunitofwork create(string contexttype); } public interface iunitofwork : idisposable { irepository<tentity> creategenericrepository<tentity>() tentity : class; void commit(); } public interface irepository<t> { iqueryable<t> find(expression<func<t, bool>> predicate); void attach(t entity); void add(t entity); // etc. }

here special ef-specific implementations:

public class unitofworkfactory : iunitofworkfactory { public iunitofwork create(string contexttype) { switch (contexttype) { case "sitemodelcontainer": homecoming new unitofwork<sitemodelcontainer>(); case "anothermodelcontainer": homecoming new unitofwork<anothermodelcontainer>(); } throw new argumentexception("unknown contexttype..."); } } public class unitofwork<tcontext> : iunitofwork tcontext : dbcontext, new() { private tcontext _dbcontext; public unitofwork() { _dbcontext = new tcontext(); } public irepository<tentity> creategenericrepository<tentity>() tentity : class { homecoming new repository<tentity>(_dbcontext); } public void commit() { _dbcontext.savechanges(); } public void dispose() { _dbcontext.dispose(); } } public class repository<t> : irepository<t> t : class { private dbcontext _dbcontext; private dbset<t> _dbset; public repository(dbcontext dbcontext) { _dbcontext = dbcontext; _dbset = dbcontext.set<t>(); } public iqueryable<t> find(expression<func<t, bool>> predicate) { homecoming _dbset.where(predicate); } public void attach(t entity) { _dbset.attach(entity); } public void add(t entity) { _dbset.add(entity); } // etc. }

your service iunitofworkfactory injected:

public class myservice { private iunitofworkfactory _factory; public myservice(iunitofworkfactory factory) { _factory = factory; } public mymethod() { using(var unitofwork1 = _factory.create("sitemodelcontainer")) { var repo1 = unitofwork1. creategenericrepository<someentitytypeinsitemodel>(); // work unitofwork1.commit(); } using(var unitofwork2 = _factory.create("anothermodelcontainer")) { var repo2 = unitofwork2. creategenericrepository<someentitytypeinanothermodel>(); // work unitofwork2.commit(); } } }

when service created concrete instance of mill injected:

var service = new myservice(new unitofworkfactory());

keep in mind hard work in abstract repository , it's implementation. don't have ef context anymore in service class have mimic lot of methods in repo interface supporting necessary scenarios manipulate data.

c# entity-framework-4.1 repository dbcontext unit-of-work

Comments

Popular posts from this blog

iphone - Dismissing a UIAlertView -

c# - Can ProtoBuf-Net deserialize to a flat class? -

javascript - Change element in each JQuery tab to dynamically generated colors -