Советы по подход к организации Мой бизнес-логики и доступа к данным?


Я исследовал различные шаблоны для построения своей бизнес-логики и доступа к данным, особенно в контексте C# и платформа Entity. Я придумал основную идею, как я думаю, я хотел бы сделать это, основываясь на нескольких ответов:

Я представляю себе UnitOfWork , который инкапсулирует IObjectContext (реферат, поэтому я могу переключать контексты для тестирования), и предоставляет хранилище интерфейс IQueryable.

interface IUnitOfWork
{
    private IObjectContext _context;

    public void SetupContext(); // Create object context here

    IQueryable<TEntity> Repository<TEntity>() 
            where TEntity : class, IEntityWithKey;
}

Я намерен писать классы обслуживания, которые содержат свою бизнес-логику и следующую структуру:

class MyService : IService
{
    public DoWork()
    {
        // Same as nesting one using within the other
        using( IUnitOfWork unitOfWork = unitOfWorkFactory.Create() ) 
        using( TransactionScope tScope = new TransactionScope() )
        {
            var repository = unitOfWork.Repository<TEntity>(); 

            /* Do some work with repository */

            unitOfWork.Commit(); // Save changes
            tScope.Complete(); // End transaction
        }
    }
}

Я схожу с ума с шаблонами проектирования? Есть ли лучший способ сделать это?



Комментарии
1 ответ

Просмотрев этот у меня есть два общих замечания в ваш код:

Сделки

Есть ли причина, чтобы использовать явные объем сделки? Когда вы вызвать метод SaveChanges на контексте, который он уже использует транзакции. Он использует транзакции или создать новую транзакцию базы данных. Так что если вы используете несколько транзакционных ресурсов (несколько соединений с базой данных, очереди сообщений и т. д.) или вызова метода SaveChanges несколько раз, вам не нужно создать транзакцию явно. Это суть единица работы, чтобы сохранить изменения в качестве одного атомного блока. Также одна сторона примечание: по умолчанию используется в метод SaveChanges использует по умолчанию (или текущий) уровень изоляции настроен на подключение к базе данных. По умолчанию для SQL Server-это читать зафиксированные;. По умолчанию уровень изоляции для transactionscope не является Сериализуемым.

Тестирование

Вы упомянули, что вы хотите сделать эту абстракцию, чтобы иметь возможность заменить контекст для тестирования. Если вы имеете в виду юнит-тестирование можно остановить и вернуться к редизайн интерфейсов. Вы не сможете полностью проверить свои бизнес-слой кода, если он использует интерфейс IQueryable (по LINQ-к-объектов) подвергается ваш уровень доступа к данным. В настоящее время нет поставщика, который может имитировать запрос LINQ-в-сущности поведения для модульных тестов. Когда же в памяти макет интерфейса IQueryable вы будете использовать LINQ-к-объектов в модульных тестах вместо. Это означает, что вы будете тестировать свой код.

Единственно правильный путь-это либо:


  • Не подвергайте интерфейса IQueryable с вашего Даля. Держать все в LINQ-в-сущности запрашивает как внутренние реализации ваших репозиториев (= вы должны материализовать результат в репозитории, например, позвонив .В список).

  • Использовать интеграционные тесты на базе реальных испытаний, а не использовать модульные тесты с издевались слой доступа к данным

Я написал несколько ответов про это проблематично на переполнение стека:

Проверьте также связаны ответы на эти вопросы.

3
ответ дан 31 июля 2011 в 10:07 Источник Поделиться