c# - Autofac DI in Using statements -




i have update method in class contains using statement create new instance of unitofwork, because i'm sending emails asynchronously , ef , dbcontext not thread safe have create new dbcontext each request. have used autofac di in unitofwork don't know how use new unitofwork constructor in using statement make sure creates new instance. please note console application. thanks

unitofwork.cs

public class unitofwork : iunitofwork {      private ieventloggerservice mailcheckerlog;     private readonly bbentities ctx = new bbentities();     private iemailrepository emailrepository;      public unitofwork(ieventloggerservice malog, iemailrepository emailrepo)     {         emailrepository = emailrepo;         mailcheckerlog = malog;     }      public iemailrepository emailrepository     {                 {              if (this.emailrepository == null)             {                 this.emailrepository = new emailrepository(ctx);             }             return emailrepository;         }     }      public void commit()     {         try         {             this.ctx.savechanges();         }         catch (exception e)         {             mailcheckerlog.log("unit of work exception => commit() => " + e.message.tostring(), eventlogentrytype.error);         }     }  } 

emailservice.cs

    public class emailservice : iemailservice     {          private iunitofwork unitofwork;         private ieventloggerservice mailcheckerlog;         private ismtpservice smtpservice;          public emailservice(ieventloggerservice log, iunitofwork uofwork, ismtpservice smtps)         {             unitofwork = uofwork;             mailcheckerlog = log;             smtpservice = smtps;             smtpservice.onmailsendcomplete += new eventhandler(sendcompletedc);         }             public void update(tb_email obj)         {             iunitofwork unitofwork2;             using (unitofwork2 = new unitofwork())             {                 unitofwork2.emailrepository.update(obj);                 unitofwork2.commit();             }         } } 

updated:

i got working following solution not sure if best way

unitofworkfactory.cs

public class unitofworkfacotry : iunitofworkfactory {      private iunitofwork uow;     private iemailrepository emailrepo;     private ieventloggerservice eventlog;      public unitofworkfacotry(ieventloggerservice malog, iemailrepository emailrep)     {          emailrepo = emailrep;         eventlog = malog;     }      public iunitofwork getcurrent()     {         return uow ?? create();     }      public iunitofwork create()     {         return new unitofwork(eventlog, emailrepo);     }  } 

emailservice.cs -> update method

    public void update(tb_email obj)     {         iunitofwork unitofwork2;         using (unitofwork2 = unitofworkfactory.create())         {             unitofwork2.emailrepository.update(obj);             unitofwork2.commit();         }     } 

while don't current implementation of uow , repository pattern in example, think can solve issue adding method called begintransaction() or similar.

this way can inject unitofworkand start using it. gives bit more flexibility on when start transaction , add logic in methods perhaps.

in case think should similar following code block.

public interface iunitofwork : idispose {     void begintransaction();     void commit(); }   public class emailservice : iemailservice {      private iunitofwork unitofwork;     private ieventloggerservice mailcheckerlog;     private ismtpservice smtpservice;      public emailservice(... iunitofwork unitofwork ..)     {         this.unitofwork = unitofwork;         //other stuff     }      public void update(tb_email obj)     {         iunitofwork unitofwork2;         using (unitofwork2.begintransaction())         {             unitofwork2.emailrepository.update(obj);             unitofwork2.commit();         }     } } 

personally i'm more fan of derek greer's suggestion (the unit of work decorator) explains quite in post: https://lostechies.com/derekgreer/2015/11/01/survey-of-entity-framework-unit-of-work-patterns/ bit more complex compared 'regular' implementations, cleaner in opinion. not promote own blog, i've written post how implement autofac.

the important code of post this.

//registration builder.registergeneric(typeof(incomingfilehandler<>)).named("commandhandler", typeof(iincomingfilehandler<>)); builder.registergenericdecorator(typeof(incomingfilehandlertransactiondecorator<>), typeof(iincomingfilehandler<>), fromkey: "commandhandler");  //the unit of work decorator public class incomingfilehandlertransactiondecorator<tcommand> : iincomingfilehandler<tcommand>      tcommand : incomingfilecommand {     private readonly iincomingfilehandler<tcommand> decorated;     private readonly idbcontext context;      public incomingfilehandlertransactiondecorator(iincomingfilehandler<tcommand> decorated, idbcontext context)     {         this.decorated = decorated;         this.context = context;     }      public void handle(tcommand command)     {         using (var transaction = context.begintransaction())         {             try             {                 decorated.handle(command)                  context.savechanges();                 context.commit(transaction);             }             catch (exception ex)             {                 context.rollback(transaction);                 throw;             }         }     } } 




wiki

Comments

Popular posts from this blog

Asterisk AGI Python Script to Dialplan does not work -

python - Read npy file directly from S3 StreamingBody -

kotlin - Out-projected type in generic interface prohibits the use of metod with generic parameter -