Не знаете, как использовать Dependency Injection + Repository Pattern + Unit Of Work Pattern с приложением WinForm - PullRequest
15 голосов
/ 21 февраля 2010

(извинения за Стену текста ... :))

Краткое описание

Использование Dependency Injection с моим приложением Winfor создает большое количество контекста репозитория. Я не уверен, правильно или неправильно я использую это, или какова обычная практика.

Детали

В последние 6 с лишним месяцев я создавал приложения ASP.NET MVC, которые реализуют шаблон Unit O fWork с шаблоном репозитория. Вдобавок ко всему, я с некоторым успехом использую инъекцию зависимостей во всех этих веб-приложениях.

Так что это пример того, как я подключил свой репозиторий.

public EntityFrameworkRepositoryRegistry() 
{ 
    For<IUnitOfWork>() 
            .HybridHttpOrThreadLocalScoped() // Lifecycle of the object.
            .Use<SqlServerContext>()  // My EF Context.
            .Ctor<string>("connectionString").Is("name=SqlServer_EF")
            .Ctor<string>("defaultContainerName").Is("Entities"); 

    // Ayende's EFProf application :) 
    EntityFrameworkProfiler.Initialize();      

    Scan(x => 
        { 
            x.TheCallingAssembly(); 

            x.ExcludeNamespaceContainingType<Fake.FakeContext>(); 

            x.WithDefaultConventions(); 
        } 
    );    
} 

Хорошо - отлично работает. Здесь главное отметить, что

  • Я предполагаю, что жизненный цикл является правильным для веб-сценария.
  • Контекст будет существовать только один раз для каждого запроса, который веб сервер.

Kewl.

Теперь для моего приложения WinForm я изначально создал один Объект Unit Of Work (без инъекций зависимостей, просто пока) и продолжал передавать этого ребенка все сервисы (а потом и в репозитории).

Для этого win-приложения оно попадает в БД, чтобы узнать весь текст файлы, которые нужно проанализировать. (например, 25 файлов). Затем для каждого файла создает новый парсер, читает каждую строку и разбирает проанализированные данные в таблица дб. Хорошо.

Проблема была в том, что этот концепт был распространен среди ВСЕХ парсеров, которые всерьез подбрасывал ошибки по всему магазину.

Итак, я добавил некоторое Dependency Injection и использовал этот код реестра выше. Сорта то же самое - много серьезных ошибок. Это потому, что снова был создан ОДИН контекст для одного потока -> winform.

Итак, теперь я настроил реестр контекста следующим образом: -

public EntityFrameworkRepositoryRegistry(bool isForTheWeb) 
{ 
    if (isForTheWeb) 
    { 
        For<IUnitOfWork>() 
            .HybridHttpOrThreadLocalScoped() 
            .Use<SqlServerContext>() 
            .Ctor<string>("connectionString").Is("name=SqlServer_EF") 
            .Ctor<string>("defaultContainerName").Is("Entities"); 
    } 
    else 
    { 
        For<IUnitOfWork>() 
            .Use<SqlServerContext>() 
            .Ctor<string>("connectionString").Is("name=SqlServer_EF") 
            .Ctor<string>("defaultContainerName").Is("Entities"); 
    } 

    EntityFrameworkProfiler.Initialize(); 

    Scan(x => 
    { 
        x.TheCallingAssembly(); 

        x.ExcludeNamespaceContainingType<Fake.FakeContext>(); 
        x.WithDefaultConventions(); 
    }); 
} 

Так что для приложения WinForm теперь не устанавливается жизненный цикл. это затем создал около 160 или около того контекста, я думаю! (Но это не совсем ошибка тоже).

Итак, я не уверен, что это правильный способ делать вещи.

Итак, мое приложение, по сути, имеет 25 различных таймеров для проверки файла каждый .. скажи .. 10 сек. Если есть новые данные, он их анализирует. В противном случае, вернитесь через 10 секунд.

Должен ли каждый из этих файлов быть проанализирован, быть его собственным потоком? а затем создать контекст для потока? (который я чувствую, похож на веб-сценарий). Или это нормально? Я знаю, что это много контекста, но каждый контекст не означает живую связь с БД .. и с пул соединений, это не должно быть проблемой.

Причина, по которой он имеет так много контекстов, заключается в следующем код ... (и это отдельные конструкторы для некоторых из Репозиторий классов ...)

public SqlServerContext(string, string); 
public GameFileRepository (IUnitOfWork); 
public LogEntryRepository(IUnitOfWork); 
public AlertRepository(IUnitOfWork); 
... etc.. 

и для основного Сервиса ...

public PunkBusterParser(IUnitOfWork, IGameFileRepositry, 
ILogEntryRepository, ILoggingService); 

поэтому для службы требуется UoW, а для каждого хранилища также требуется один .. что означает, что для каждого создается новый.

Я уверен, что я не правильно структурировал это ...

Любые предложения были бы искренне благодарны!

1 Ответ

3 голосов
/ 21 февраля 2010

Эта статья Ayende может дать вам некоторое представление о том, как управлять вашей единицей работы в настольном приложении (общая идея - использовать «сеанс на докладчика»): http://msdn.microsoft.com/en-us/magazine/ee819139.aspx

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...