in business logic layer of entity framework-based application, methods acting on db should (as i've heard) included within:
using(funkycontainer fc = new funkycontainer()) { // thing fc.savechanges(); } of course, own convenience times methods use each other, sake of not repeating myself. risk see here following:
public void mainmethod() { using(funkycontainer fc = new funkycontainer()) { // perform operations on fc // modify few objects downloaded db int x = helpermethod(); // act on fc again fc.savechanges(); } } public int helpermethod() { using(funkycontainer fc2 = new funkycontainer()) { // act on fc2 then: fc2.savechanges(); return 42; } } i doesn't me, when container fc2 created, while fc still open , has not been saved yet. leads question number one:
- is having multiple containers open @ same time , acting on them carelessly acceptable practice?
i came conclusion, write simple guard-styled object this:
public sealed class funkycontaineraccessguard : idisposable { private static funkycontainer globalcontainer { get; private set; } public funkycontainer container // non-static adapter syntactic convenience { { return globalcontainer; } } private bool isrootofhierarchy { get; set; } public funkycontaineraccessguard() { isrootofhierarchy = (globalcontainer == null); if (isrootofhierarchy) globalcontainer = new funkycontainer(); } public void dispose() { if (isrootofhierarchy) { globalcontainer.dispose(); globalcontainer = null; } } } now usage following:
public void mainmethod() { using(funkycontaineraccessguard guard = new funkycontaineraccessguard()) { funkycontainer fc = guard.container; // fc int x = helpermethod(); fc.savechanges(); } } public int helpermethod() { using(funkycontaineraccessguard guard = new funkycontaineraccessguard()) { funkycontainer fc2 = guard.container; // fc2 fc2.savechanges(); } } when helpermethod called mainmethod, globalcontainer created, , used both methods, there no conflict. moreover, helpermethod can used separately, , creates own container.
however, seems massive overkill me; so:
- has problem been solved in form of class (ioc?) or @ least nice design pattern?
thank you.
- is having multiple containers open @ same time , acting on them carelessly acceptable practice?
generally acceptable, necessary, have caucious that. have multiple containers @ same time handy when doing multithreading operations. because of how db works each thread should have own dbcontext should not shared other threads. downside using multiple dbcontext @ same time each of them use separate db connection, , limited, may lead application being unable connect database. other downside fact entity generated 1 dbcontext may not used entity generated other dbcontext. in example helpermethod returns primitive type, safe, if return entity object in mainmethod assign instance navigation property of entity created mainmethod dbcontext receive exception. overcome in mainmethod have use id of entity returned helpermethod retrieve entity once more, time fc context. on other hand there advantage of using multiple contexts - if 1 context have troubles, instance tried save violated index constaint, next trials of saving changes result in same exception faulty change still pending. if use multiple dbcontexts if 1 fail, second operate independently - why dbcontexts should not live long. best usage rule be:
- each thread should use separate dbcontext
- all methods executes on same thread should share same dbcontext
of course above applies if job done short. dbcontext should not live long. best example web applications - there each server request handled separate thread , operations generate response not take long. in such case methods executed generate 1 response should share convenience same dbcontext. each request should served separate dbcontext.
- has problem been solved in form of class (ioc?) or @ least nice design pattern?
what need assure dbcontext class singleton per thread, each thread has own instance of class. in opinion best way assure ioc. instance in autofac in web applications register dbcontext following rule:
builder .registertype<mydbcontext>() .instanceperhttprequest(); this way autofac ioc generates 1 dbcontext per request , share existing instance within request serving thread. not need care here disposing dbcontext. ioc when thread over.
Comments
Post a Comment