Отлично, рад, что смог помочь. :)
отаю над включением некоторой общей инфраструктуры репозитория в некоторые приложения, которые обертывают службы данных EF, L2SQL и WCF (хотя базовые реализации доступа к данным должны быть произвольными). Я прочитал немного по этому вопросу, но не могу найти пример, который действительно удовлетворяет.
Я начал с:
public interface IRepository : IDisposable
{
IQueryable<T> Query<T>();
void Attach(object entity);
void ForDeletion(object entity);
void SaveChanges();
}
Но мне нравится идея репозитория с узкимдомен контракты (http://codebetter.com/blogs/gregyoung/archive/2009/01/16/ddd-the-generic-repository.aspx). Вышесказанное оставляет потребителю знать все типы сущностей, поддерживаемые хранилищем.
Я не собираюсь говорить, что об этом не может быть и речи, но мне будет очень трудно убедиться, что сами IQueryables не должны быть частью контракта с репозиторием. Я не фанат кода котельной плиты, и я твердо верю, что чем больше у вас есть, тем больше черных дыр обслуживания вы вводите. Итак, я говорю, что было бы очень трудно убедить меня в том, что все выглядит так:
Public IEnumerable<Customer> GetCustomersWithFirstNameOf(string _Name) {
internalGenericRepository.FetchByQueryObject(new CustomerFirstNameOfQuery(_Name)); //could be hql or whatever
}
что-нибудь, кроме совершеннобездонный идея. Как насчет того, когда вы хотите искать по имениа также Фамилия. Или имяили же фамилия ... и т. д. В итоге вы получите репозиторий с 1000+ операциями, половина из которых повторяет ту же логику. ПРИМЕЧАНИЕ: я НЕ вызывающий код должен отвечать за применение всей фильтрации и тому подобное, скорее, для меня имеет смысл иметь источник дополнительной спецификации:
public static class CustomerSpecifications
{
public IQueryable<Customer> WithActiveSubscriptions(this IQueryable<Customer> customers, DateTime? start, DateTime? end)
{
// expression manipulation
return customers;
}
}
// bind some data source
repository.GetQueryable().WithActiveSubscriptions();
Итак, двигаясь вперед, я думаю, что наличие явных репозиториев с моделью предметной области звучит как хорошая идея в следующем формате:
public interface IRepository : IDisposable
{
void SaveChanges();
}
public interface IRepository<T>: IRepository
{
IQueryable<T> GetQueryable();
void Attach(T entity);
void ForDeletion(T entity);
}
затем
public class CustomerRepository:IRepository<Customer>
{
private ObjectContext _context;
// trivial implementation
}
но моя проблема с этим заключается в том, что он позволяет только удалять клиентов. Как насчет случая, когда я хочу удалить адрес Клиента? То есть я использую репозиторий для запроса сущности Customer, но затем хочу удалить myCustomer.CustomerAddresses [0]? Мне нужно создать второй репозиторий, чтобы просто присоединить и удалить адрес, который я хочу?
Я думаю, что мой CustomerRepository может быть:
public class CustomerRepository:IRepository<Customer>, IRepository<CustomerAddress>
{
private ObjectContext _context;
// trivial implementation
}
что позволило бы мне повторно использовать репозиторий для удаления CustomerAddresses, но я не уверен, что я думаю о наследованииIRepository<T>
для каждой части графика я хочу выставить удаления для ...
public class CustomerRepository:IRepository<Customer>, IRepository<CustomerAddress> /* this list may get pretty long, and then I really just have a masked EF ObjectContext, don't I? */
{
У кого-нибудь есть предложения по лучшей реализации?