Внедрение схемы работы
Сначала создаю приложение с помощью кода структуры MVC MVC и Entity. Я использую репозиторий и шаблон работы с влиянием следующей ссылки.
http://www.asp.net/mvc/tutorials/getting-started-with-ef-5-using-mvc-4/implementing-the-repository-and-unit-of-work-patterns-in-an-asp-net-mvc-application
Здесь у меня есть вопрос о реализации Unit of Work в том, что ссылка на работу выполняется через прямое создание сущностей в самом классе.
public class UnitOfWork : IDisposable
{
private SchoolContext context = new SchoolContext();
private GenericRepository<Department> departmentRepository;
public GenericRepository<Department> DepartmentRepository
{
get
{
if (this.departmentRepository == null)
{
this.departmentRepository = new GenericRepository<Department>(context);
}
return departmentRepository;
}
}
}
Считаете ли вы, что реализация достаточно хороша, потому что каждый раз, когда я добавляю/удаляю объекты, мне нужно изменить свою Единицу рабочего класса. Я считаю, что Единица работы не должна зависеть от организаций. Поскольку в моем приложении, основанном на отзывах Клиента, мы часто будем добавлять/удалять объекты.
Я могу казаться глупым, но дайте мне знать ваши взгляды на это.
Ответы
Ответ 1
Шаблон "Единица работы" уже реализован в Entity Framework.
DbContext - это ваше подразделение работы.
Каждый IDbSet является репозиторием.
using (var context = new SchoolContext()) // instantiate our Unit of Work
{
var department = context.Departments.Find(id);
}
Ответ 2
Существует несколько разновидностей UnitOfWorkPattern. Тот, который вы описываете, - это показать все, есть и скрыть все. В подходе к скрытию единица работы ссылается на метод DbContext.SaveChanges() и ничего больше; звучит так, как вы хотите.
public YourContext : DbContext, IContext{}
public interface IUnitOfWork{
void Commit();
}
public UnitOfWork : IUnitOfWork{
private readonly IContext _context;
//IOC should always inject the same instance of this, register it accordingly
public UnitOfWork(IContext context){
_context = context;
}
void Commit(){
// try catch the validation exception if you want to return the validations this
// way if your confident you've already validated you can put a void here or
// return the intfrom save changes make sure you handle the disposing properly,
// not going into that here you also may be doing other stuff here, have multiple
// "contexts" to save in a single transaction or we have contextProcessors that
// do stuff based on items in the context
_context.SaveChanges();
}
}
Это оставляет вопрос о том, как вы получаете свои репозитории в классы, которые им нужны, если вы не принимаете их из UnitOfWork. Это лучше всего использовать в рамках МОК. Опять здесь есть пара вариантов. Однажды зарегистрируйте UnitOfWork как один экземпляр для каждого запроса и внесите его в свой пользовательский класс репозитория.
public interface IRepository<T>
{
IQueryable<T> Records();
//other methods go here
}
public Repository : IRepository<T>
{
private IContext _context;
// same instance of context injected into the unit of work, this why when you Commit
// everything will save, this can get tricky if you start adding Add, Update and stuff
// but EF does have the support needed.
public Repository(IContext context)
{
_context = context;
}
public Records()
{
return _context.Set<T>();
}
}
public class SomeService : ISomeService{
private readonly _myObjectRepository;
public SomeService(IRepository<MyObject> myObjectRepository){
_myObjectRepository = myObjectRepository;
}
}
Лично я считаю IDbSet достаточной абстракцией, поэтому я больше не создаю репозитории. В
чтобы ввести IDbSets из контекста, хотя вам необходимо зарегистрировать их как экземпляры, которые вы
извлечение из контекста в настройке IOC. Это может быть сложным и зависит от ваших навыков
может оказаться в ситуации, когда вам необходимо зарегистрировать каждый IDbSet, который, как я знаю, вы пытаетесь избежать.
Какая приятность в использовании IDbSet заключается в том, что у вас есть доступ к простым методам, например Add, и вы можете избежать некоторых более сложных частей работы с Entity и DbEntity в общем смысле.
public class SomeService : ISomeService {
private readonly _myObjectSet;
// requires specialized IOC configurations because you have to pull this instance from
// the instance of the context, personally don't know how to do this with a single
// registration so this has the same problem as having to add each new repository to the
// unit of work. In this case each new Entity I add to the context requires I add an IOC
// registration for the type.
public SomeService(IDbSet<MyObject> myObjectSet){
_myObjectSet= myObjectSet;
}
}
Ответ 3
Попробуйте передать SchoolContext в GenericRepository:
public GenericRepository<T>
{
private SchoolContext _context;
public GenericRepository(SchoolContext context)
{
_context = context;
}
public Get(int id)
{
return _context.Set<T>().Find(id);
}
}
И используйте:
using(var context = new SchoolContext())
{
var departmentRepository = new GenericRepository<Department>(context);
var department = departmentRepository.Get(1);
}