Properly Disposing a context with Unit of Work Pattern Dependency Injection in WPF
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
add a comment |
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
add a comment |
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
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
wpf dependency-injection repository ninject dbcontext
edited Nov 15 '18 at 16:29
Selthien
asked Nov 15 '18 at 16:12
SelthienSelthien
1298
1298
add a comment |
add a comment |
1 Answer
1
active
oldest
votes
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.
add a comment |
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
);
);
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
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.
add a comment |
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.
add a comment |
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.
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.
answered Nov 15 '18 at 18:54
SelthienSelthien
1298
1298
add a comment |
add a comment |
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.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
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