I have a Data Layer that uses one Unit of work that is is basically a wrapper of the EnityFramework data context.
With all the async await stuff going around, I thought I'd start trying to use this data layer with some async calls. (I'm new to asynchronous programming in general)
I quickly ran into the problem of "there is already an open data reader associated with this command" errors.
Is there a good way to make my Unit of work thread-safe? Or should I just be creating another instance of it when i'm about to make some calls (in others words..be more careful).
Are there any good resources to check out for doing this?
My few google searches didn't amount to much, so I thought I'd bring this question to SO.
My Uow looks something like this.
public class MyUnitOfWork: IMyUnitOfWork, IDisposable
{
private MyDbContext DbContext { get; set; }
protected IRepositoryProvider RepositoryProvider;
public MyUnitOfWork(IRepositoryProvider repositoryProvider)
{
CreateDbContext();
repositoryProvider.DbContext = DbContext;
RepositoryProvider = repositoryProvider;
}
public MyUnitOfWork(IRepositoryProvider repositoryProvider, MyDbContext context)
{
DbContext = context;
repositoryProvider.DbContext = DbContext;
RepositoryProvider = repositoryProvider;
}
public void CreateDbContext()
{
DbContext = new MyDbContext();
//Serialization false if we enable proxied entities
DbContext.Configuration.ProxyCreationEnabled = false;
//avoid serilaization trouble
DbContext.Configuration.LazyLoadingEnabled = false;
}
public void Commit()
{
DbContext.SaveChanges();
}
public IRepository<Person> Persons {get { return repositoryProvider.GetRepo<Person>(); } }
public IRepository<SomeOtherEntityType> SomeOtherType {get { return repositoryProvider.GetRepo<SomeOtherEntityType>(); } }
// IDisposable
// ...
}
This article has general guidelines on how to operate with DbContext, regarding lifetime, multithreading, etc.
http://msdn.microsoft.com/en-us/data/jj729737.aspx
Related
I see a lot of questions and answers on this topic, however the vast majority are dealing with ASP.Net or other web based applications and something called .InRequestScope. I have yet to find this method in Ninject with a Windows Application.
I have the usual Unit of Work (UoW) and Repository (Repo) classes and Interfaces, but I am wanting to inject the same DbContext into both, each time a UoW is run from the DIContainer. My code looks like this;
public class UnitOfWork : IUnitOfWork, IDisposable
{
private readonly FinancialContext _context;
private IAccountRepository _accountRepository;
public IAccountRepository Accounts
{
get { return _accountRepository; }
}
UnitOfWork(IMyContext context, IAccountRepository accountRepository)
{
_context = context;
_accountRepository = accountRepository;
}
public void SaveChanges()
{
_context.SaveChanges();
}
public void Dispose()
{
_context.Dispose();
}
}
public class AccountRepository : Repository<Account>, IAccountRepository
{
public AccountRepository(IMyContext context) : base(context) { }
}
The DIContainer holds the following associations;
Bind<IUnitOfWork>().To<UnitOfWork>().InTransientScope();
Bind<IUnitOfWorkFactory>().ToFactory();
Bind<IMyContext>().To<MyContext>().InSingletonScope();
Bind<IAccountTypeRepository>().To<AccountTypeRepository>().InTransientScope();
I'll come back to the .InSingletonScope();
The way I have seen people do this normally has been in the UoW Properties for each Repo to have code to this effect;
private IAccountRepository _accountRepository;
public IAccountRepository Accounts
{
get
{
if(_accountRepository = null)
{
_accountRepository = new AccountRepository(_context);
}
return _accountRepository;
}
}
And remove the injected repositories from the Constructor, there by ensuring that each instance of a repository using the same _context.
However in my mind this breaks the Dependency Injection for this class. Is there a way to do this where each creation of a UoW like so;
public TestUnitOfWork(IUnitOfWorkFactory unitOfWork)
{
using (var UoW = unitOfWork.Create())
{
Work done on UoW...
}
}
Currently the .InSingletonScope allows this, but is this keeping an instance of the context always open? Introducing the errors associated with not disposing a context properly?
Or is it better to create a Factory for the Repositories and give them a context parameter, then in the properties initialise it like so;
private IAccountRepository _accountRepository;
public IAccountRepository Accounts
{
get
{
if(_accountRepository = null)
{
_accountRepository = RepositoryFactory.CreateAccountRepository(_context);
}
return _accountRepository;
}
}
Thanks in advance for any help!
The solution is the use Ninject's Extensions.Factory class and pass in an IAccountFactory.Create() to initialise a new object. This then uses the DI Container to resolve its dependencies and doesn't break the DI approach.
I am writing a new C# application on the top of Prism 6.3 framework using the well-known MVVM design pattern. I am using Unity IoC container to help me manage my dependencies.
I am using Entity Framework Core to interact with the database. However, I don't want to tightly couple my application to Entity Framework Core, so I implemented Repository and UnitOfWork patterns to make it easy for me to swap out the Entity Framework Core implementation if needed.
My repository implementation provides a method called Save() which calls EF Core's SaveChanges() method. The repositories are injected into my business-service so that my business-service expose one method to do a single task. For example, if I want to create a new order, I would call the Create(orderViewModel) method which internally calls the Add() and the Save() method on the OrderRepository.
Additionally, the UnitOfWork provides Save(), BeginTransaction(), Commit() and Rollback() methods which allow me control the transaction behavior. In another words it will give me the flexibility to either commit or rollback the SQL transaction when needed.
To explain my use case better, here is an example of how I would add new order to my database directly using the business-service without transaction or unit-of-work.
OrdersService.Create(orderViewModel); // this will call the `Add` and the `Save()` methods on the OrderRepository;
Here is another example which demonstrate how I would add a new order and order-items to my database using the business-services while using unit-of-work to start transaction and control the transaction.
using(var transaction = UnitOfWork.BeginTransaction())
{
try
{
var order = OrdersService.Create(orderViewModel);
OrdersService.CreateRange(order.Id, orderItemsViewModel);
transaction.Commit();
}
catch(Exception e)
{
Log.Add(e);
transaction.RollBack();
}
}
In the second example above, even-though the OrdersService.Save and OrdersService.SaveRange each call the SaveChanges() method the data are not committed to the database since I am wrapping them with a transaction.
Question: what LifeTimeManager should I register the DbContext, IUnitOfWork and each of my repositories with?
In a web environment, I would register everything using PerRequestLifetimeManager then during the request I am reusing the same DbContext and everything works fine and the DbContext is disposed at the end of the http request. But not sure how to register everything in a WPF application where I can still use transaction to control everything while allowing the repository to call the SaveChanges()
If needed here is my EntityRepository implementation
public class EntityRepository<TEntity, TKeyType> : IRepository<TEntity, TKeyType>
where TEntity : class
where TKeyType : struct
{
protected readonly DbContext Context;
protected readonly DbSet<TEntity> DbSet;
public EntityRepository(DbContext context)
{
Context = context;
DbSet = context.Set<TEntity>();
}
public TEntity Get(TKeyType id)
{
return DbSet.Find(id);
}
public IEnumerable<TEntity> GetAll()
{
return DbSet.ToList();
}
public bool Any(Expression<Func<TEntity, bool>> predicate)
{
return DbSet.Any(predicate);
}
public IQueryable<TEntity> Find(Expression<Func<TEntity, bool>> predicate)
{
return DbSet.Where(predicate);
}
public TEntity SingleOrDefault(Expression<Func<TEntity, bool>> predicate)
{
return DbSet.SingleOrDefault(predicate);
}
public virtual TEntity Add(TEntity entity)
{
var record = Context.Add(entity);
record.State = EntityState.Added;
return entity;
}
public virtual IEnumerable<TEntity> AddRange(IEnumerable<TEntity> entities)
{
Context.AddRange(entities);
return entities;
}
public void Remove(TEntity entity)
{
Context.Remove(entity).State = EntityState.Deleted;
}
public void RemoveRange(IEnumerable<TEntity> entities)
{
Context.RemoveRange(entities);
}
public void Update(TEntity entity)
{
DbSet.Attach(entity);
var record = Context.Entry(entity);
record.State = EntityState.Modified;
}
public IQueryable<TEntity> Query()
{
return DbSet;
}
public void Save()
{
Context.SaveChanges();
}
}
And here is my unit of work implementation
public sealed class UnitOfWork : IUnitOfWork
{
private bool IsDisposed = false;
private readonly DbContext Context;
public IOrderRepository Orders { get; private set; }
public IOrderItemRepository OrderItems { get; private set; }
public UnitOfWork(DbContext context)
{
Context = context;
Orders = new OrderRepository(context);
OrderItems = new OrderItemRepository(context);
}
public int Save()
{
Context.SaveChanges();
return 0;
}
public void Dispose()
{
Dispose(true);
}
public IDatabaseTransaction BeginTransaction()
{
return new EntityDatabaseTransaction(Context);
}
private void Dispose(bool disposing)
{
if (IsDisposed)
{
return;
}
if (disposing)
{
Context.Dispose();
}
IsDisposed = true;
}
}
Transient (an instance per view) lifetime would be the way to go if your DI doesn't support scoping, but then you would need to abstract away your DbContext being passed through into the repo's and unitOfWork, otherwise new instances of the DbContext will be passed in there. On construction of the page, a new instance is created, and on moving away from that view, that DBContext should be disposed of. UnitOfWork would follow the same path as you wouldn't want a UnitOfWork spanning multiple instances of a DBContext.
See http://blogs.microsoft.co.il/gilf/2010/02/07/entity-framework-context-lifetime-best-practices/. Otherwise, if your DI has the concept of container hierarchies, and you're able to create a container scope per view, then a singleton would work in this instance and you wouldn't need any abstractions mentioned above and would be quite a bit easier to work with.
I'm using EF for the first time, in a WPF application, using MVVM pattern. I read a lot of stuff but I couldn't end up with a solution. My problem is how to integrate EF in my app.
The most common way I found is build your own Repository + UnitOfWork. I don't like it. Basically because I already have DbContext and DbSet that can work as unit of work and repository, so why reinvent the wheel?
So I tried to use DbContext directly from view models like this
public class BookCollectionViewModel : ViewModelBase
{
public void LoadCollection()
{
Books.clear();
var books = new List<Book>();
using(var ctx = new DbContext())
{
books = ctx.DbSet<Book>().ToList();
}
books.Foreach(b => Books.Add(b));
}
ObservableCollection<Book> Books { get; } = new ObservableCollection<Book>();
}
But I don't like to use DbContext directly from view models, so I built a service layer
public class DbServices
{
public TReturn Execute<TEntity>(Func<IDbSet<TEntity>, TReturn> func)
{
TReturn retVal = default(TReturn);
using(var ctx = new DbContext())
{
retVal = func(ctx.DbSet<TEntity>());
}
return retVal;
}
}
public class BookCollectionViewModel : ViewModelBase
{
private DbServices mDbServices = new DbServices();
public void LoadCollection()
{
Books.clear();
var books = mDbServices.Execute<Book>((dbSet) => return dbSet.ToList());
books.Foreach(b => Books.Add(b))
}
ObservableCollection<Book> Books { get; } = new ObservableCollection<Book>();
}
But this way every action is atomic, so when I modify an entity I have to call SaveChanges() every time or loose changes, because DbContext is always disposed. So why not create a class-wide DbContext?
public class DbServices
{
private Lazy<> mContext;
public DbServices()
{
mContext = new Lazy<TContext>(() => {return new DbContext();});
}
public TContext Context { get { return context.Value; } }
public TReturn Execute<TEntity>(Func<IDbSet<TEntity>, TReturn> func)
{
return func(Context.DbSet<TEntity>());
}
}
Unfortunately, this way again doesn't work, because once a dbcontext is created, it is never disposed... So how about explicitly Open/Close the DbContext?
The question is: Where and how should I create/dispose the DbContext? The only thing I'm sure of is that I don't want to rebuild repository and unit of work, since they already exist as DbContext and DbSet...
I'm in the same position. I find that any persistent repository on the client side causes users not to see each others' changes.
Here's a good video explaining why EF is not the same as a repository
https://www.youtube.com/watch?v=rtXpYpZdOzM
Also I found an excellent end-to-end tutorial on WPF,MVVM & EF
http://www.software-architects.com/devblog/2010/09/10/MVVM-Tutorial-from-Start-to-Finish.
In this he exposes the data through a WCF data service and detaches them from the dbcontext straight away.
Hope it helps
I have inherited a Windows service where all the dependencies are created when the service starts and are injected in the transient scope.
We are having a number of problems with this service, not least we have a DbContext which lives for the whole time the service is running, and different instances of it are injected each time.
I would like to refactor so that each worker thread gets it’s own DbContext injected which will live for just the duration of each tick.
I have looked at the custom scope. It looks fine for a single threaded app, but not multi-threaded. I also considered InThreadScope. Whilst that would give each thread it’s own instance, they are singletons as far as the thread is concerned so it does not fulfil the per tick requirement.
My current thinking is to use the named scope extension and to inject a scope factory which I can use to create a new scope on every tick.
Is this the way to go? Any suggestions, tips or alternatives would be appreciated.
UPDATE
Due to a time constraint we ended up using the named scope, but it wasn't as clean as #BatteryBackupUnit's solution. There were some dependencies further down the graph which needed a DbContext and we had to inject the scope factory again to get it. Using #BatteryBackupUnit's solution we could have reused the same instance from the ThreadLocal storage instead.
Regarding Named Scope: Consider that when you are creating a DbContext from the same thread but from an object (p.Ex. factory) which was created before the scope was created, it won't work. Either it will fail because there is no scope, or it will inject another instance of DbContext because there is a different scope.
If you don't do this, then a scope like named scope or call scope can work for you.
We are doing the following instead:
When a DbContext is requested, we check a ThreadLocal
(http://msdn.microsoft.com/de-de/library/dd642243%28v=vs.110%29.aspx) whether there is already one. In case there is, we use that one. Otherwise, we create a new one and assign it to the ThreadLocal<DbContext>.Value.
Once all operations are done, we release the DbContext and reset the ThreadLocal<DbContext>.Value.
See this (simplified, not perfect) code for an example:
public interface IUnitOfWork
{
IUnitOfWorkScope Start();
}
internal class UnitOfWork : IUnitOfWork
{
public static readonly ThreadLocal<IUnitOfWorkScope> LocalUnitOfWork = new ThreadLocal<IUnitOfWorkScope>();
private readonly IResolutionRoot resolutionRoot;
public UnitOfWork(IResolutionRoot resolutionRoot)
{
this.resolutionRoot = resolutionRoot;
}
public IUnitOfWorkScope Start()
{
if (LocalUnitOfWork.Value == null)
{
LocalUnitOfWork.Value = this.resolutionRoot.Get<IUnitOfWorkScope>();
}
return LocalUnitOfWork.Value;
}
}
public interface IUnitOfWorkScope : IDisposable
{
Guid Id { get; }
}
public class UnitOfWorkScope : IUnitOfWorkScope
{
public UnitOfWorkScope()
{
this.Id = Guid.NewGuid();
}
public Guid Id { get; private set; }
public void Dispose()
{
UnitOfWork.LocalUnitOfWork.Value = null;
}
}
public class UnitOfWorkIntegrationTest : IDisposable
{
private readonly IKernel kernel;
public UnitOfWorkIntegrationTest()
{
this.kernel = new StandardKernel();
this.kernel.Bind<IUnitOfWork>().To<UnitOfWork>();
this.kernel.Bind<IUnitOfWorkScope>().To<UnitOfWorkScope>();
}
[Fact]
public void MustCreateNewScopeWhenOldOneWasDisposed()
{
Guid scopeId1;
using (IUnitOfWorkScope scope = this.kernel.Get<IUnitOfWork>().Start())
{
scopeId1 = scope.Id;
}
Guid scopeId2;
using (IUnitOfWorkScope scope = this.kernel.Get<IUnitOfWork>().Start())
{
scopeId2 = scope.Id;
}
scopeId1.Should().NotBe(scopeId2);
}
[Fact]
public void NestedScope_MustReuseSameScope()
{
Guid scopeId1;
Guid scopeId2;
using (IUnitOfWorkScope scope1 = this.kernel.Get<IUnitOfWork>().Start())
{
scopeId1 = scope1.Id;
using (IUnitOfWorkScope scope2 = this.kernel.Get<IUnitOfWork>().Start())
{
scopeId2 = scope2.Id;
}
}
scopeId1.Should().Be(scopeId2);
}
[Fact]
public void MultipleThreads_MustCreateNewScopePerThread()
{
var unitOfWork = this.kernel.Get<IUnitOfWork>();
Guid scopeId1;
Guid scopeId2 = Guid.Empty;
using (IUnitOfWorkScope scope1 = unitOfWork.Start())
{
scopeId1 = scope1.Id;
Task otherThread = Task.Factory.StartNew(() =>
{
using (IUnitOfWorkScope scope2 = unitOfWork.Start())
{
scopeId2 = scope2.Id;
}
},
TaskCreationOptions.LongRunning);
if (!otherThread.Wait(TimeSpan.FromSeconds(5)))
{
throw new TimeoutException();
}
}
scopeId2.Should().NotBeEmpty();
scopeId1.Should().NotBe(scopeId2);
}
public void Dispose()
{
this.kernel.Dispose();
}
}
Note: i'm using nuget packages: ninject, xUnit.Net, Fluent Assertions
Also note, that you can replace the IUnitOfWork.Start with a ToProvider<IUnitOfWorkScope>() binding. Of course you need to implement the corresponding logic in the provider.
A proper unit-of-work scope, implemented in Ninject.Extensions.UnitOfWork, solves this problem.
Setup:
_kernel.Bind<IService>().To<Service>().InUnitOfWorkScope();
Usage:
using(UnitOfWorkScope.Create()){
// resolves, async/await, manual TPL ops, etc
}
I'm going to test my EF Models. In order to do this I've create IDbContext class. But I don't know how to rewrite my Save and Delete methods, because I don't know how to write
db.Partner.AddObject(obj); How to rewrite these methods?
public interface IDbContext
{
int SaveChanges();
DbSet<Partner> Partner { get; set; }
}
public class PartnerRepository : IPartnerRepository
{
readonly IDbContext _context;
public PartnerRepository()
{
_context = (IDbContext)new VostokPortalEntities();
}
public PartnerRepository(IDbContext context)
{
_context = context;
}
public void Save(Partner obj)
{
using (var db = new VostokPortalEntities())
{
if (obj.PartnerID == 0)
{
db.Partner.AddObject(obj);
}
else
{
db.Partner.Attach(obj);
db.ObjectStateManager.ChangeObjectState(obj, System.Data.EntityState.Modified);
}
db.SaveChanges();
}
}
public void Delete(Partner obj)
{
using (var db = new VostokPortalEntities())
{
db.Partner.Attach(obj);
db.ObjectStateManager.ChangeObjectState(obj, System.Data.EntityState.Deleted);
db.SaveChanges();
}
}
public List<Partner> GetAll()
{
using (var db = new VostokPortalEntities())
{
return db.Partner.OrderByDescending(i => i.PartnerID).ToList();
}
}
}
Is this proper way to test EF Models?
Unit-testing of repositories takes a lot of time and does not give you many benefits. Why? Because repository don't have complex business logic. Usually there is pretty simple calls to underlying data-access API (i.e. ORM). I think it's match better to spend time on writing full-stack acceptance tests, which also will show if your repository do its job.
BTW there is interesting rule Don't Mock what you don't own:
By testing interactions with a mocked version of type we don't own, we
really are not using our test to check for the correct behavior, nor
to drive out a collaborator’s design. All our test is doing is
reiterating our guess as to how the other type works. Sure, it’s
better than no test, but not necessarily by much.