Интерфейс для блока шаблона работы и шаблона repository


Я пытаюсь разработать четко определенные и простой интерфейс для работы и модели репозитория. Мое Ву подвержены услуг и услуг затем "получить хранилищ", что он должен на запрос. Я знаю, что вернувшись интерфейс IQueryable для хранилищ-это религиозные войны. Потому что хранилищ подвергаются только к службе, все запросы выполняются внутри сервиса, и поэтому я могу проверить запросы. Есть все, что я должен изменить для этих интерфейсов? Все критические замечания будут с благодарностью!

public interface IUnitOfWork : IDisposable
{
    bool IsActive { get; }

    bool WasCommitted { get; }

    /// <summary>
    /// Commits all changes made on the unit of work.
    /// </summary>
    void Commit();

    bool WasRolledBack { get; }

    /// <summary>
    /// Rolls back all changes made on the unit of work.
    /// </summary>
    void Rollback();

    /// <summary>
    /// Returns an instance of an entity with the specified key that is attached to the unit of work without
    /// loading the entity from a repository.
    /// </summary>
    /// <param name="id"></param>
    /// <returns></returns>
    T Load<T>(int id)
        where T : class;

    void Attach<T>(T entity)
        where T : class, IIdentifiable;

    void Detach<T>(T entity)
        where T : class;

    IRepository<T> GetRepository<T>()
        where T : class;
}

public interface IRepository<T>
    where T : class
{

    IUnitOfWork UnitOfWork { get; }

    void Add(T entity);

    void Remove(T entity);

    /// <summary>
    /// Returns an instance of an entity with the specified key that is attached to the unit of work by loading
    /// the entity from the repository.
    /// </summary>
    /// <param name="id"></param>
    /// <returns></returns>
    T Get(int id);

    IQueryable<T> All();
}


12800
23
задан 27 января 2011 в 02:01 Источник Поделиться
Комментарии
3 ответа

Я думаю, что ваши интерфейсы в основном четко определена, с парой исключений:

Я не думаю, что нагрузки, присоединения и отсоединения должны быть членами IUnitOfWork, а IRepository. Похоже, что репозиторий, который управляет объектами типа T будет лучшее место методы места, который действует на этого типа.

Свойство UnitOfWork на IRepository ему не принадлежит. Вещи, которые изменяют одно хранилище не должно быть позволено пойти и получить другие хранилища изменить на свои собственные. Если они им нужны, передайте их в явном виде. В противном случае, вы скрываете от потенциальных абонентов на то, что реализация на самом деле зависит от более чем одного репозитория, и скрывая свои зависимости, как ты стыдишься из них является одним из моих нелюбимых запахов кода.

2
ответ дан 29 января 2011 в 08:01 Источник Поделиться

Ваш интерфейс нарушает закон Деметры. Или просто сказал, Я не могу использовать IUnitOfWork UnitOfWork { получить; } на IRespository без понимания IUnitOfWork.

Я бы тоже менять IRespository

public interface IRepository<T>
where T : class
{

bool IsActive { get; }

bool WasCommitted { get; }

/// <summary>
/// Commits all changes made on the unit of work.
/// </summary>
void Commit();

bool WasRolledBack { get; }

/// <summary>
/// Rolls back all changes made on the unit of work.
/// </summary>
void Rollback();

/// <summary>
/// Returns an instance of an entity with the specified key that is attached to the unit of work without
/// loading the entity from a repository.
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
T Load<T>(int id)
where T : class;

void Attach<T>(T entity)
where T : class, IIdentifiable;

void Detach<T>(T entity)
where T : class;

IRepository<T> GetRepository<T>()
where T : class;

void Add(T entity);

void Remove(T entity);

/// <summary>
/// Returns an instance of an entity with the specified key that is attached to the unit of work by loading
/// the entity from the repository.
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
T Get(int id);

IQueryable<T> All();
}

Обратите внимание, как она является копией IUnitOfWork, это UnitOfWork действительно нужны.

Как ты создал интерфейс?

Это где вы должны делать по TDD. Написать тест сначала о том, что вы хотите, чтобы код делать. Тогда ваш интерфейс должен быть создан для того, чтобы выполнить тест.

Например, если вы вызовите метод отката(); и не может написать тест были WasRollbacked собственность, они вам может и не нужна собственность.

Не более чем требуется для любого интерфейса. Их интерфейс становится шум. Я бы порекомендовал читать Чистый код Роберта Мартина , чтобы понять эти идеи в глубине пути.

0
ответ дан 27 января 2011 в 05:01 Источник Поделиться

Я не помню точно, где я их выполнению, но многое заимствовано из весенних рамок...

Только три метода, которые мой IUnitOfWork интерфейс предоставляет несколько инициализации(), совершить () и rollback(). Затем я унаследовал от, что для INhibernateUnitOfWork, который просто выставляет программе NHibernate сессии по недвижимости, а также... я думаю, это может зависеть от того, что вы используете для сохранения системы хранения...

Но то, что он позволяет мне делать в мой класс репозитория, то это просто взять на единицу работы в качестве инъекций зависимостей. По сути, каждый мой вам(ИД), нагрузки(ИД), найти(), сохранить(), обновления () и т. д. методы просто сделать звонок против репозитория.UnitOfWork.Сессии собственность.

По сути, это очень близко к тому, что вы уже реализовали... не знаю, почему вы хотите, чтобы метод GetRepository, но вы можете иметь какое-то дело к чему я не. Для меня моя UnitOfWork это запрос времени жизни объекта, чей метод initialize() и commit () и rollback() функциональность обрабатывается http-модуль подключения на BeginRequest и события EndRequest. То есть, экземпляр UnitOfWork только когда-либо тронут, - сказал модуль HTTP, и репозиториями, которые просто использовать его, чтобы получить ссылку на текущий объект Session.

0
ответ дан 27 января 2011 в 09:01 Источник Поделиться