Properly Disposing a context with Unit of Work Pattern Dependency Injection in WPF










1















I have been trying to use DI within my Unit of Work / Repository pattern in WPF. The problem I am running into currently is if I make a call to a repository like _UserRepo.Add(User) and an exception is thrown. Every new call to the repository throws the exception because the context is never disposed of.



What I have tried



Unit Of Work



 public class UnitOfWork : IUnitOfWork

private DbContextTransaction _trans;
private BomConfiguratorContext _context;

public UnitOfWork(BomConfiguratorContext context)

_context = context;
_trans = context.Database.BeginTransaction();


public void Dispose()

try

_context.SaveChanges();
_trans.Commit();

catch (Exception)

_trans.Rollback();

finally

_context.Dispose(); //This obviously does not work





Unit Of Work Factory



 public class UnitOfWorkFactory : IUnitOfWorkFactory

private BomConfiguratorContext _context;
public UnitOfWorkFactory(BomConfiguratorContext context)

_context = context;

public UnitOfWork Create()

return new UnitOfWork(_context);




My Generic Repository



public interface IRepository<TEntity> where TEntity : class

void Add(TEntity entity);
void AddRange(IEnumerable<TEntity> entities);

void Remove(TEntity entity);
void RemoveRange(IEnumerable<TEntity> entities);

TEntity Get(int id);
IEnumerable<TEntity> GetAll();
IEnumerable<TEntity> Find(Expression<Func<TEntity, bool>> predicate);

void Update(TEntity entity);



Generic Repository Implementation



 public class Repository<TEntity> : IRepository<TEntity> where TEntity : class

protected readonly BomConfiguratorContext Context;

public Repository(BomConfiguratorContext context)

Context = context;

public virtual void Add(TEntity entity)

Context.Set<TEntity>().Add(entity);


public void AddRange(IEnumerable<TEntity> entities)

Context.Set<TEntity>().AddRange(entities);


public IEnumerable<TEntity> Find(Expression<Func<TEntity, bool>> predicate)

return Context.Set<TEntity>().Where(predicate);


public TEntity Get(int id)

return Context.Set<TEntity>().Find(id);


public IEnumerable<TEntity> GetAll()

return Context.Set<TEntity>().ToList();


public void Remove(TEntity entity)

Context.Set<TEntity>().Remove(entity);


public void RemoveRange(IEnumerable<TEntity> entities)

Context.Set<TEntity>().RemoveRange(entities);

public void Update(TEntity entity)

Context.Set<TEntity>().Attach(entity);
Context.Entry(entity).State = System.Data.Entity.EntityState.Modified;




User Repository



public class UserRepository : Repository<User>,IUserRepository

public UserRepository(BomConfiguratorContext context)
:base(context)






Use Case



using (var UOW = _UnitOfWorkFactory.Create())

//Submit the user
_UserRepository.Add(ExampleNewUser);




So currently I am using MVVM Light to do all my DI work, now I understand with mvvm light you can only inject with singleton scope. So I am pretty sure I will end up having to switch over to something like Ninject so I can utilize their .InTransientScope or .InNamedScope (from what I have been reading).



Obviously the above code will not work with MVVM Light since the context is never properly disposed of.



The Question



So my question to you is if I were to swap over to using Ninject and start injecting my Context into these repositories / unit of work. How do I properly configure it to AWLAYS inject a new context within my unit of work for the repositories.



I read that Ninject MVC has .InRequestScope which would solve the issue entirely. But what about for WPF? How do you achieve the same kind of injection?



I can't seem to find the exact solution/pattern or maybe there is a better way to do this? Any suggestions and help would be greatly appreciated.










share|improve this question




























    1















    I have been trying to use DI within my Unit of Work / Repository pattern in WPF. The problem I am running into currently is if I make a call to a repository like _UserRepo.Add(User) and an exception is thrown. Every new call to the repository throws the exception because the context is never disposed of.



    What I have tried



    Unit Of Work



     public class UnitOfWork : IUnitOfWork

    private DbContextTransaction _trans;
    private BomConfiguratorContext _context;

    public UnitOfWork(BomConfiguratorContext context)

    _context = context;
    _trans = context.Database.BeginTransaction();


    public void Dispose()

    try

    _context.SaveChanges();
    _trans.Commit();

    catch (Exception)

    _trans.Rollback();

    finally

    _context.Dispose(); //This obviously does not work





    Unit Of Work Factory



     public class UnitOfWorkFactory : IUnitOfWorkFactory

    private BomConfiguratorContext _context;
    public UnitOfWorkFactory(BomConfiguratorContext context)

    _context = context;

    public UnitOfWork Create()

    return new UnitOfWork(_context);




    My Generic Repository



    public interface IRepository<TEntity> where TEntity : class

    void Add(TEntity entity);
    void AddRange(IEnumerable<TEntity> entities);

    void Remove(TEntity entity);
    void RemoveRange(IEnumerable<TEntity> entities);

    TEntity Get(int id);
    IEnumerable<TEntity> GetAll();
    IEnumerable<TEntity> Find(Expression<Func<TEntity, bool>> predicate);

    void Update(TEntity entity);



    Generic Repository Implementation



     public class Repository<TEntity> : IRepository<TEntity> where TEntity : class

    protected readonly BomConfiguratorContext Context;

    public Repository(BomConfiguratorContext context)

    Context = context;

    public virtual void Add(TEntity entity)

    Context.Set<TEntity>().Add(entity);


    public void AddRange(IEnumerable<TEntity> entities)

    Context.Set<TEntity>().AddRange(entities);


    public IEnumerable<TEntity> Find(Expression<Func<TEntity, bool>> predicate)

    return Context.Set<TEntity>().Where(predicate);


    public TEntity Get(int id)

    return Context.Set<TEntity>().Find(id);


    public IEnumerable<TEntity> GetAll()

    return Context.Set<TEntity>().ToList();


    public void Remove(TEntity entity)

    Context.Set<TEntity>().Remove(entity);


    public void RemoveRange(IEnumerable<TEntity> entities)

    Context.Set<TEntity>().RemoveRange(entities);

    public void Update(TEntity entity)

    Context.Set<TEntity>().Attach(entity);
    Context.Entry(entity).State = System.Data.Entity.EntityState.Modified;




    User Repository



    public class UserRepository : Repository<User>,IUserRepository

    public UserRepository(BomConfiguratorContext context)
    :base(context)






    Use Case



    using (var UOW = _UnitOfWorkFactory.Create())

    //Submit the user
    _UserRepository.Add(ExampleNewUser);




    So currently I am using MVVM Light to do all my DI work, now I understand with mvvm light you can only inject with singleton scope. So I am pretty sure I will end up having to switch over to something like Ninject so I can utilize their .InTransientScope or .InNamedScope (from what I have been reading).



    Obviously the above code will not work with MVVM Light since the context is never properly disposed of.



    The Question



    So my question to you is if I were to swap over to using Ninject and start injecting my Context into these repositories / unit of work. How do I properly configure it to AWLAYS inject a new context within my unit of work for the repositories.



    I read that Ninject MVC has .InRequestScope which would solve the issue entirely. But what about for WPF? How do you achieve the same kind of injection?



    I can't seem to find the exact solution/pattern or maybe there is a better way to do this? Any suggestions and help would be greatly appreciated.










    share|improve this question


























      1












      1








      1








      I have been trying to use DI within my Unit of Work / Repository pattern in WPF. The problem I am running into currently is if I make a call to a repository like _UserRepo.Add(User) and an exception is thrown. Every new call to the repository throws the exception because the context is never disposed of.



      What I have tried



      Unit Of Work



       public class UnitOfWork : IUnitOfWork

      private DbContextTransaction _trans;
      private BomConfiguratorContext _context;

      public UnitOfWork(BomConfiguratorContext context)

      _context = context;
      _trans = context.Database.BeginTransaction();


      public void Dispose()

      try

      _context.SaveChanges();
      _trans.Commit();

      catch (Exception)

      _trans.Rollback();

      finally

      _context.Dispose(); //This obviously does not work





      Unit Of Work Factory



       public class UnitOfWorkFactory : IUnitOfWorkFactory

      private BomConfiguratorContext _context;
      public UnitOfWorkFactory(BomConfiguratorContext context)

      _context = context;

      public UnitOfWork Create()

      return new UnitOfWork(_context);




      My Generic Repository



      public interface IRepository<TEntity> where TEntity : class

      void Add(TEntity entity);
      void AddRange(IEnumerable<TEntity> entities);

      void Remove(TEntity entity);
      void RemoveRange(IEnumerable<TEntity> entities);

      TEntity Get(int id);
      IEnumerable<TEntity> GetAll();
      IEnumerable<TEntity> Find(Expression<Func<TEntity, bool>> predicate);

      void Update(TEntity entity);



      Generic Repository Implementation



       public class Repository<TEntity> : IRepository<TEntity> where TEntity : class

      protected readonly BomConfiguratorContext Context;

      public Repository(BomConfiguratorContext context)

      Context = context;

      public virtual void Add(TEntity entity)

      Context.Set<TEntity>().Add(entity);


      public void AddRange(IEnumerable<TEntity> entities)

      Context.Set<TEntity>().AddRange(entities);


      public IEnumerable<TEntity> Find(Expression<Func<TEntity, bool>> predicate)

      return Context.Set<TEntity>().Where(predicate);


      public TEntity Get(int id)

      return Context.Set<TEntity>().Find(id);


      public IEnumerable<TEntity> GetAll()

      return Context.Set<TEntity>().ToList();


      public void Remove(TEntity entity)

      Context.Set<TEntity>().Remove(entity);


      public void RemoveRange(IEnumerable<TEntity> entities)

      Context.Set<TEntity>().RemoveRange(entities);

      public void Update(TEntity entity)

      Context.Set<TEntity>().Attach(entity);
      Context.Entry(entity).State = System.Data.Entity.EntityState.Modified;




      User Repository



      public class UserRepository : Repository<User>,IUserRepository

      public UserRepository(BomConfiguratorContext context)
      :base(context)






      Use Case



      using (var UOW = _UnitOfWorkFactory.Create())

      //Submit the user
      _UserRepository.Add(ExampleNewUser);




      So currently I am using MVVM Light to do all my DI work, now I understand with mvvm light you can only inject with singleton scope. So I am pretty sure I will end up having to switch over to something like Ninject so I can utilize their .InTransientScope or .InNamedScope (from what I have been reading).



      Obviously the above code will not work with MVVM Light since the context is never properly disposed of.



      The Question



      So my question to you is if I were to swap over to using Ninject and start injecting my Context into these repositories / unit of work. How do I properly configure it to AWLAYS inject a new context within my unit of work for the repositories.



      I read that Ninject MVC has .InRequestScope which would solve the issue entirely. But what about for WPF? How do you achieve the same kind of injection?



      I can't seem to find the exact solution/pattern or maybe there is a better way to do this? Any suggestions and help would be greatly appreciated.










      share|improve this question
















      I have been trying to use DI within my Unit of Work / Repository pattern in WPF. The problem I am running into currently is if I make a call to a repository like _UserRepo.Add(User) and an exception is thrown. Every new call to the repository throws the exception because the context is never disposed of.



      What I have tried



      Unit Of Work



       public class UnitOfWork : IUnitOfWork

      private DbContextTransaction _trans;
      private BomConfiguratorContext _context;

      public UnitOfWork(BomConfiguratorContext context)

      _context = context;
      _trans = context.Database.BeginTransaction();


      public void Dispose()

      try

      _context.SaveChanges();
      _trans.Commit();

      catch (Exception)

      _trans.Rollback();

      finally

      _context.Dispose(); //This obviously does not work





      Unit Of Work Factory



       public class UnitOfWorkFactory : IUnitOfWorkFactory

      private BomConfiguratorContext _context;
      public UnitOfWorkFactory(BomConfiguratorContext context)

      _context = context;

      public UnitOfWork Create()

      return new UnitOfWork(_context);




      My Generic Repository



      public interface IRepository<TEntity> where TEntity : class

      void Add(TEntity entity);
      void AddRange(IEnumerable<TEntity> entities);

      void Remove(TEntity entity);
      void RemoveRange(IEnumerable<TEntity> entities);

      TEntity Get(int id);
      IEnumerable<TEntity> GetAll();
      IEnumerable<TEntity> Find(Expression<Func<TEntity, bool>> predicate);

      void Update(TEntity entity);



      Generic Repository Implementation



       public class Repository<TEntity> : IRepository<TEntity> where TEntity : class

      protected readonly BomConfiguratorContext Context;

      public Repository(BomConfiguratorContext context)

      Context = context;

      public virtual void Add(TEntity entity)

      Context.Set<TEntity>().Add(entity);


      public void AddRange(IEnumerable<TEntity> entities)

      Context.Set<TEntity>().AddRange(entities);


      public IEnumerable<TEntity> Find(Expression<Func<TEntity, bool>> predicate)

      return Context.Set<TEntity>().Where(predicate);


      public TEntity Get(int id)

      return Context.Set<TEntity>().Find(id);


      public IEnumerable<TEntity> GetAll()

      return Context.Set<TEntity>().ToList();


      public void Remove(TEntity entity)

      Context.Set<TEntity>().Remove(entity);


      public void RemoveRange(IEnumerable<TEntity> entities)

      Context.Set<TEntity>().RemoveRange(entities);

      public void Update(TEntity entity)

      Context.Set<TEntity>().Attach(entity);
      Context.Entry(entity).State = System.Data.Entity.EntityState.Modified;




      User Repository



      public class UserRepository : Repository<User>,IUserRepository

      public UserRepository(BomConfiguratorContext context)
      :base(context)






      Use Case



      using (var UOW = _UnitOfWorkFactory.Create())

      //Submit the user
      _UserRepository.Add(ExampleNewUser);




      So currently I am using MVVM Light to do all my DI work, now I understand with mvvm light you can only inject with singleton scope. So I am pretty sure I will end up having to switch over to something like Ninject so I can utilize their .InTransientScope or .InNamedScope (from what I have been reading).



      Obviously the above code will not work with MVVM Light since the context is never properly disposed of.



      The Question



      So my question to you is if I were to swap over to using Ninject and start injecting my Context into these repositories / unit of work. How do I properly configure it to AWLAYS inject a new context within my unit of work for the repositories.



      I read that Ninject MVC has .InRequestScope which would solve the issue entirely. But what about for WPF? How do you achieve the same kind of injection?



      I can't seem to find the exact solution/pattern or maybe there is a better way to do this? Any suggestions and help would be greatly appreciated.







      wpf dependency-injection repository ninject dbcontext






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited Nov 15 '18 at 16:29







      Selthien

















      asked Nov 15 '18 at 16:12









      SelthienSelthien

      1298




      1298






















          1 Answer
          1






          active

          oldest

          votes


















          1














          My solution to the problem was to create a ContextFactory.



          Interface



          public interface IContextFactory

          BomConfiguratorContext Create();
          BomConfiguratorContext Get();



          Context Factory



          The Factory allows me to either Get an existing context or create a new context.



          public class ContextFactory : IContextFactory

          private BomConfiguratorContext _context;

          public ContextFactory(BomConfiguratorContext context)

          _context = context;


          public BomConfiguratorContext Create()

          _context = new BomConfiguratorContext();
          return _context;


          public BomConfiguratorContext Get()

          return _context;




          New Base Repository



          By calling the ContextFactory.Get() method I use the cached context instead of creating a new one.



           public class Repository<TEntity> : IRepository<TEntity> where TEntity : class

          protected readonly IContextFactory ContextFactory;

          public Repository(IContextFactory factory)

          ContextFactory = factory;

          public virtual void Add(TEntity entity)


          ContextFactory.Get().Set<TEntity>().Add(entity);


          public void AddRange(IEnumerable<TEntity> entities)


          ContextFactory.Get().Set<TEntity>().AddRange(entities);



          public IEnumerable<TEntity> Find(Expression<Func<TEntity, bool>> predicate)

          return ContextFactory.Get().Set<TEntity>().Where(predicate);


          public TEntity Get(int id)

          return ContextFactory.Get().Set<TEntity>().Find(id);


          public IEnumerable<TEntity> GetAll()

          return ContextFactory.Get().Set<TEntity>().ToList();


          public void Remove(TEntity entity)

          ContextFactory.Get().Set<TEntity>().Remove(entity);


          public void RemoveRange(IEnumerable<TEntity> entities)

          ContextFactory.Get().Set<TEntity>().RemoveRange(entities);

          public void Update(TEntity entity)

          ContextFactory.Get().Set<TEntity>().Attach(entity);
          ContextFactory.Get().Entry(entity).State = System.Data.Entity.EntityState.Modified;




          New Unit Of Work Factory



          When the factory is Create() method is called I call the context factory's Create() method to create a new context.



          public class UnitOfWorkFactory : IUnitOfWorkFactory

          private IContextFactory _contextFactory;

          public UnitOfWorkFactory(IContextFactory factory)

          _contextFactory = factory;

          public UnitOfWork Create()

          return new UnitOfWork(_contextFactory.Create());




          By doing it this way I am now able to inject my context factory into all my repositories. I attempted to use the Ninject scopes mentioned above in the original question but ended up causing issues with injecting two separate contexts, one in my unit of work factory and one in my repositories.






          share|improve this answer






















            Your Answer






            StackExchange.ifUsing("editor", function ()
            StackExchange.using("externalEditor", function ()
            StackExchange.using("snippets", function ()
            StackExchange.snippets.init();
            );
            );
            , "code-snippets");

            StackExchange.ready(function()
            var channelOptions =
            tags: "".split(" "),
            id: "1"
            ;
            initTagRenderer("".split(" "), "".split(" "), channelOptions);

            StackExchange.using("externalEditor", function()
            // Have to fire editor after snippets, if snippets enabled
            if (StackExchange.settings.snippets.snippetsEnabled)
            StackExchange.using("snippets", function()
            createEditor();
            );

            else
            createEditor();

            );

            function createEditor()
            StackExchange.prepareEditor(
            heartbeatType: 'answer',
            autoActivateHeartbeat: false,
            convertImagesToLinks: true,
            noModals: true,
            showLowRepImageUploadWarning: true,
            reputationToPostImages: 10,
            bindNavPrevention: true,
            postfix: "",
            imageUploader:
            brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
            contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
            allowUrls: true
            ,
            onDemand: true,
            discardSelector: ".discard-answer"
            ,immediatelyShowMarkdownHelp:true
            );



            );













            draft saved

            draft discarded


















            StackExchange.ready(
            function ()
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53323562%2fproperly-disposing-a-context-with-unit-of-work-pattern-dependency-injection-in-w%23new-answer', 'question_page');

            );

            Post as a guest















            Required, but never shown

























            1 Answer
            1






            active

            oldest

            votes








            1 Answer
            1






            active

            oldest

            votes









            active

            oldest

            votes






            active

            oldest

            votes









            1














            My solution to the problem was to create a ContextFactory.



            Interface



            public interface IContextFactory

            BomConfiguratorContext Create();
            BomConfiguratorContext Get();



            Context Factory



            The Factory allows me to either Get an existing context or create a new context.



            public class ContextFactory : IContextFactory

            private BomConfiguratorContext _context;

            public ContextFactory(BomConfiguratorContext context)

            _context = context;


            public BomConfiguratorContext Create()

            _context = new BomConfiguratorContext();
            return _context;


            public BomConfiguratorContext Get()

            return _context;




            New Base Repository



            By calling the ContextFactory.Get() method I use the cached context instead of creating a new one.



             public class Repository<TEntity> : IRepository<TEntity> where TEntity : class

            protected readonly IContextFactory ContextFactory;

            public Repository(IContextFactory factory)

            ContextFactory = factory;

            public virtual void Add(TEntity entity)


            ContextFactory.Get().Set<TEntity>().Add(entity);


            public void AddRange(IEnumerable<TEntity> entities)


            ContextFactory.Get().Set<TEntity>().AddRange(entities);



            public IEnumerable<TEntity> Find(Expression<Func<TEntity, bool>> predicate)

            return ContextFactory.Get().Set<TEntity>().Where(predicate);


            public TEntity Get(int id)

            return ContextFactory.Get().Set<TEntity>().Find(id);


            public IEnumerable<TEntity> GetAll()

            return ContextFactory.Get().Set<TEntity>().ToList();


            public void Remove(TEntity entity)

            ContextFactory.Get().Set<TEntity>().Remove(entity);


            public void RemoveRange(IEnumerable<TEntity> entities)

            ContextFactory.Get().Set<TEntity>().RemoveRange(entities);

            public void Update(TEntity entity)

            ContextFactory.Get().Set<TEntity>().Attach(entity);
            ContextFactory.Get().Entry(entity).State = System.Data.Entity.EntityState.Modified;




            New Unit Of Work Factory



            When the factory is Create() method is called I call the context factory's Create() method to create a new context.



            public class UnitOfWorkFactory : IUnitOfWorkFactory

            private IContextFactory _contextFactory;

            public UnitOfWorkFactory(IContextFactory factory)

            _contextFactory = factory;

            public UnitOfWork Create()

            return new UnitOfWork(_contextFactory.Create());




            By doing it this way I am now able to inject my context factory into all my repositories. I attempted to use the Ninject scopes mentioned above in the original question but ended up causing issues with injecting two separate contexts, one in my unit of work factory and one in my repositories.






            share|improve this answer



























              1














              My solution to the problem was to create a ContextFactory.



              Interface



              public interface IContextFactory

              BomConfiguratorContext Create();
              BomConfiguratorContext Get();



              Context Factory



              The Factory allows me to either Get an existing context or create a new context.



              public class ContextFactory : IContextFactory

              private BomConfiguratorContext _context;

              public ContextFactory(BomConfiguratorContext context)

              _context = context;


              public BomConfiguratorContext Create()

              _context = new BomConfiguratorContext();
              return _context;


              public BomConfiguratorContext Get()

              return _context;




              New Base Repository



              By calling the ContextFactory.Get() method I use the cached context instead of creating a new one.



               public class Repository<TEntity> : IRepository<TEntity> where TEntity : class

              protected readonly IContextFactory ContextFactory;

              public Repository(IContextFactory factory)

              ContextFactory = factory;

              public virtual void Add(TEntity entity)


              ContextFactory.Get().Set<TEntity>().Add(entity);


              public void AddRange(IEnumerable<TEntity> entities)


              ContextFactory.Get().Set<TEntity>().AddRange(entities);



              public IEnumerable<TEntity> Find(Expression<Func<TEntity, bool>> predicate)

              return ContextFactory.Get().Set<TEntity>().Where(predicate);


              public TEntity Get(int id)

              return ContextFactory.Get().Set<TEntity>().Find(id);


              public IEnumerable<TEntity> GetAll()

              return ContextFactory.Get().Set<TEntity>().ToList();


              public void Remove(TEntity entity)

              ContextFactory.Get().Set<TEntity>().Remove(entity);


              public void RemoveRange(IEnumerable<TEntity> entities)

              ContextFactory.Get().Set<TEntity>().RemoveRange(entities);

              public void Update(TEntity entity)

              ContextFactory.Get().Set<TEntity>().Attach(entity);
              ContextFactory.Get().Entry(entity).State = System.Data.Entity.EntityState.Modified;




              New Unit Of Work Factory



              When the factory is Create() method is called I call the context factory's Create() method to create a new context.



              public class UnitOfWorkFactory : IUnitOfWorkFactory

              private IContextFactory _contextFactory;

              public UnitOfWorkFactory(IContextFactory factory)

              _contextFactory = factory;

              public UnitOfWork Create()

              return new UnitOfWork(_contextFactory.Create());




              By doing it this way I am now able to inject my context factory into all my repositories. I attempted to use the Ninject scopes mentioned above in the original question but ended up causing issues with injecting two separate contexts, one in my unit of work factory and one in my repositories.






              share|improve this answer

























                1












                1








                1







                My solution to the problem was to create a ContextFactory.



                Interface



                public interface IContextFactory

                BomConfiguratorContext Create();
                BomConfiguratorContext Get();



                Context Factory



                The Factory allows me to either Get an existing context or create a new context.



                public class ContextFactory : IContextFactory

                private BomConfiguratorContext _context;

                public ContextFactory(BomConfiguratorContext context)

                _context = context;


                public BomConfiguratorContext Create()

                _context = new BomConfiguratorContext();
                return _context;


                public BomConfiguratorContext Get()

                return _context;




                New Base Repository



                By calling the ContextFactory.Get() method I use the cached context instead of creating a new one.



                 public class Repository<TEntity> : IRepository<TEntity> where TEntity : class

                protected readonly IContextFactory ContextFactory;

                public Repository(IContextFactory factory)

                ContextFactory = factory;

                public virtual void Add(TEntity entity)


                ContextFactory.Get().Set<TEntity>().Add(entity);


                public void AddRange(IEnumerable<TEntity> entities)


                ContextFactory.Get().Set<TEntity>().AddRange(entities);



                public IEnumerable<TEntity> Find(Expression<Func<TEntity, bool>> predicate)

                return ContextFactory.Get().Set<TEntity>().Where(predicate);


                public TEntity Get(int id)

                return ContextFactory.Get().Set<TEntity>().Find(id);


                public IEnumerable<TEntity> GetAll()

                return ContextFactory.Get().Set<TEntity>().ToList();


                public void Remove(TEntity entity)

                ContextFactory.Get().Set<TEntity>().Remove(entity);


                public void RemoveRange(IEnumerable<TEntity> entities)

                ContextFactory.Get().Set<TEntity>().RemoveRange(entities);

                public void Update(TEntity entity)

                ContextFactory.Get().Set<TEntity>().Attach(entity);
                ContextFactory.Get().Entry(entity).State = System.Data.Entity.EntityState.Modified;




                New Unit Of Work Factory



                When the factory is Create() method is called I call the context factory's Create() method to create a new context.



                public class UnitOfWorkFactory : IUnitOfWorkFactory

                private IContextFactory _contextFactory;

                public UnitOfWorkFactory(IContextFactory factory)

                _contextFactory = factory;

                public UnitOfWork Create()

                return new UnitOfWork(_contextFactory.Create());




                By doing it this way I am now able to inject my context factory into all my repositories. I attempted to use the Ninject scopes mentioned above in the original question but ended up causing issues with injecting two separate contexts, one in my unit of work factory and one in my repositories.






                share|improve this answer













                My solution to the problem was to create a ContextFactory.



                Interface



                public interface IContextFactory

                BomConfiguratorContext Create();
                BomConfiguratorContext Get();



                Context Factory



                The Factory allows me to either Get an existing context or create a new context.



                public class ContextFactory : IContextFactory

                private BomConfiguratorContext _context;

                public ContextFactory(BomConfiguratorContext context)

                _context = context;


                public BomConfiguratorContext Create()

                _context = new BomConfiguratorContext();
                return _context;


                public BomConfiguratorContext Get()

                return _context;




                New Base Repository



                By calling the ContextFactory.Get() method I use the cached context instead of creating a new one.



                 public class Repository<TEntity> : IRepository<TEntity> where TEntity : class

                protected readonly IContextFactory ContextFactory;

                public Repository(IContextFactory factory)

                ContextFactory = factory;

                public virtual void Add(TEntity entity)


                ContextFactory.Get().Set<TEntity>().Add(entity);


                public void AddRange(IEnumerable<TEntity> entities)


                ContextFactory.Get().Set<TEntity>().AddRange(entities);



                public IEnumerable<TEntity> Find(Expression<Func<TEntity, bool>> predicate)

                return ContextFactory.Get().Set<TEntity>().Where(predicate);


                public TEntity Get(int id)

                return ContextFactory.Get().Set<TEntity>().Find(id);


                public IEnumerable<TEntity> GetAll()

                return ContextFactory.Get().Set<TEntity>().ToList();


                public void Remove(TEntity entity)

                ContextFactory.Get().Set<TEntity>().Remove(entity);


                public void RemoveRange(IEnumerable<TEntity> entities)

                ContextFactory.Get().Set<TEntity>().RemoveRange(entities);

                public void Update(TEntity entity)

                ContextFactory.Get().Set<TEntity>().Attach(entity);
                ContextFactory.Get().Entry(entity).State = System.Data.Entity.EntityState.Modified;




                New Unit Of Work Factory



                When the factory is Create() method is called I call the context factory's Create() method to create a new context.



                public class UnitOfWorkFactory : IUnitOfWorkFactory

                private IContextFactory _contextFactory;

                public UnitOfWorkFactory(IContextFactory factory)

                _contextFactory = factory;

                public UnitOfWork Create()

                return new UnitOfWork(_contextFactory.Create());




                By doing it this way I am now able to inject my context factory into all my repositories. I attempted to use the Ninject scopes mentioned above in the original question but ended up causing issues with injecting two separate contexts, one in my unit of work factory and one in my repositories.







                share|improve this answer












                share|improve this answer



                share|improve this answer










                answered Nov 15 '18 at 18:54









                SelthienSelthien

                1298




                1298





























                    draft saved

                    draft discarded
















































                    Thanks for contributing an answer to Stack Overflow!


                    • Please be sure to answer the question. Provide details and share your research!

                    But avoid


                    • Asking for help, clarification, or responding to other answers.

                    • Making statements based on opinion; back them up with references or personal experience.

                    To learn more, see our tips on writing great answers.




                    draft saved


                    draft discarded














                    StackExchange.ready(
                    function ()
                    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53323562%2fproperly-disposing-a-context-with-unit-of-work-pattern-dependency-injection-in-w%23new-answer', 'question_page');

                    );

                    Post as a guest















                    Required, but never shown





















































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown

































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown







                    這個網誌中的熱門文章

                    Barbados

                    How to read a connectionString WITH PROVIDER in .NET Core?

                    Node.js Script on GitHub Pages or Amazon S3