0
\$\begingroup\$

I know using a UnitOfWork/Repository pattern in a normal class should work fine without any issues but how about using them in a static class/methods (I mean using a private static IUnitOfWork instance, refer CustomerService class). Will this work fine in multiple user scenario without overlapping with other request (I am using asp.net)?

Can anyone please tell me whether the below code looks fine or I will get any issues (overlapping db issues) going forward because of the static IUnitOfWork instance? Also, please advice me if there is any other better way to do this.

public interface IDataRepository<T> where T : class
{
 IQueryable<T> Find(Expression<Func<T, bool>> predicate);
 IQueryable<T> GetAll();
 T GetById(Guid id);
 T GetById(int id); 
 void Add(T entity);
 void Update(T entity);
 void Remove(T entity);
}
public class DataRepository<T> : IDataRepository<T> where T : class
{
}
public interface IUnitOfWork
{
 IDataRepository<Customer> CustomerRepository { get; }
 IDataRepository<Product> ProductRepository { get; }
 void SaveChanges();
}
public class UnitOfWork : IUnitOfWork
{
 private readonly SomeContext _context;
 private IDataRepository<Customer> _customerRepository { get; set; }
 private IDataRepository<Product> _productRepository { get; set; }
 public UnitOfWork()
 {
 _context = new SomeContext();
 } 
 public IDataRepository<Customer> CustomerRepository
 {
 get
 {
 if (_customerRepository == null)
 {
 _customerRepository = new DataRepository<Customer>(_context);
 }
 return _customerRepository;
 }
 }
 public IDataRepository<Product> CustomerRepository
 {
 get
 {
 if (_productRepository == null)
 {
 _productRepository = new DataRepository<Product>(_context);
 }
 return _productRepository;
 }
 }
}
public class CustomerService
{
 private static IUnitOfWork _unitOfWork = new UnitOfWork();
 public static List<Customer> GetCustomers()
 {
 _unitOfWork.CustomerRepository.Find(t => t.ID == 123).ToList();
 }
 public static bool IsCustomerExist()
 {
 return (_unitOfWork.CustomerRepository.Find(t => t.ID == 123).Count() > 0);
 }
 public static bool UpdateCustomer(Customer customer)
 {
 .....
 _unitOfWork.SaveChanges();
 }
}
asked Jul 25, 2013 at 16:06
\$\endgroup\$

1 Answer 1

1
\$\begingroup\$

It entirely depends on your implementation of the unit of works members. If the IDataRepository is using something like NHibernate and keeping open persistent connections (which, being part of a unit of work, I presume it might) you will absolutely run into weird database connectivity issues when using a private static member.

The reason for this, is that the static property is shared between all instances of the CustomerService, in your example, so you'll have one of those, and it'll be constructed with "whatever it gets at the time" - for example, the first database connection or session your application opens. If you have some sort of session per request handling that subsequently disposes of that session, the static class will still hold a reference to it, and you'll have a bad time.

To deal with this problem in some things that "must be" static, there's a cheap little trick you can use - add a static func to some form of resolver or container that you wire up at bootstrapping time:

public class ContainerRegistrationCode
{
 public void RegisterTypesInContainer()
 {
 Kernel.Bind<IUnitOfWork>().To<UnitOfWork>().InRequestScope();
 CustomerService.GetCurrentUnitOfWork = () => Kernel.GetService<IUnitOfWork>();
 }
}
public class CustomerService
{
 public static Func<IUnitOfWork> GetCurrentUnitOfWork { get; set; }
 public static List<Customer> GetCustomers()
 {
 var currentUnitOfWork = GetCurrentUnitOfWork ();
 currentUnitOfWork.CustomerRepository.Find(t => t.ID == 123).ToList();
 }
}

This way, you delegate out to a container or something that can manage the lifecycle of the unit of work, and every time you use it in a static context, you call the func which gets whatever the current one is.

It's a bit of a hack, don't use statics, use a good container instead that supports scoping (like Ninject) and you just shouldn't have this problem.

answered Aug 20, 2013 at 8:20
\$\endgroup\$

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.