Я пытался использовать DI в своем шаблоне Unit of Work / Repository в WPF.Проблема, с которой я сталкиваюсь в настоящее время, заключается в том, что я делаю вызов в хранилище, такое как _UserRepo.Add (User), и выдается исключение.Каждый новый вызов репозитория генерирует исключение, потому что контекст никогда не удаляется.
Что я пробовал
Единица работы
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
}
}
}
Фабрика единиц работы
public class UnitOfWorkFactory : IUnitOfWorkFactory
{
private BomConfiguratorContext _context;
public UnitOfWorkFactory(BomConfiguratorContext context)
{
_context = context;
}
public UnitOfWork Create()
{
return new UnitOfWork(_context);
}
}
Мой универсальный репозиторий
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);
}
Реализация универсального репозитория
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;
}
}
Репозиторий пользователя
public class UserRepository : Repository<User>,IUserRepository
{
public UserRepository(BomConfiguratorContext context)
:base(context)
{
}
}
Вариант использования
using (var UOW = _UnitOfWorkFactory.Create())
{
//Submit the user
_UserRepository.Add(ExampleNewUser);
}
Так что в настоящее время яиспользуя MVVM Light для выполнения всей моей работы с DI, теперь я понимаю, что с помощью mvvm light вы можете вводить только с помощью singleton scope.Поэтому я уверен, что в конечном итоге мне придется переключиться на что-то вроде Ninject, чтобы я мог использовать их .InTransientScope или .InNamedScope (из того, что я читал).
Очевидно, что приведенный выше код не будет работать сMVVM Light, поскольку контекст никогда не удаляется должным образом.
Вопрос
Итак, мой вопрос к вам, если бы я переключился на использование Ninject и начал внедрять свой контекст в эти репозитории / единицы работы.Как правильно настроить его так, чтобы AWLAYS вводил новый контекст в моей единице работы для репозиториев.
Я прочитал, что в Ninject MVC есть .InRequestScope, который полностью решит проблему.Но как насчет WPF?Как вы добиваетесь инъекций такого же типа?
Кажется, я не могу найти точное решение / схему или, может быть, есть лучший способ сделать это?Будем весьма благодарны за любые предложения и помощь.