Отлично, рад, что смог помочь. :)

отаю над включением некоторой общей инфраструктуры репозитория в некоторые приложения, которые обертывают службы данных 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? */
{

У кого-нибудь есть предложения по лучшей реализации?

Ответы на вопрос(1)

Ваш ответ на вопрос