2015-07-20 1 views
0

У меня есть приложение ASP.NET MVC, в котором мой контроллер вызывает команду invoker для выполнения операций CRUD. Обработчики команд находятся в моей сборке уровня домена. Один из обработчиков команд сохраняет запись, используя следующий код:Развязка объекта ObjectContext

public class SaveTransactionCommandHandler : ICommandHandler<SaveTransactionCommand> 
{ 
    public void Handle(SaveTransactionCommand command) 
    { 
     using (GiftCardEntities db = new GiftCardEntities()) 
     { 
      db.Transactions.AddObject(new Transaction 
      { 
       GiftCardId = command.GiftCardId, 
       TransactionTypeId = Convert.ToInt32(command.TransactionTypeId), 
       Amount = command.Amount, 
       TransactionDate = DateTime.Now 
      }); 
      db.SaveChanges(); 
     } 
    } 
} 

Однако, как вы можете видеть, мой обработчик зависит от ObjectContext (EF). Я изучаю Injection Dependency с Ninject. Теперь я знаю, что мой обработчик (объект домена) не должен зависеть от каких-либо объектов уровня данных. Но в моем случае обработчик зависит от GiftCardEntities, который является ObjectContext. Как изменить обработчик так, чтобы он был отделен от ObjectContext?

ответ

3

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

public class SaveTransactionCommandHandler : ICommandHandler<SaveTransactionCommand> 
{ 
    readonly ITransactionRepository repository; 

    public SaveTransactionCommandHandler(ITransactionRepository repository) 
    { 
      this.repository = repository; 
    } 
    public void Handle(SaveTransactionCommand command) 
    { 

      repository.Save(new Transaction 
      { 
       GiftCardId = command.GiftCardId, 
       TransactionTypeId = Convert.ToInt32(command.TransactionTypeId), 
       Amount = command.Amount, 
       TransactionDate = DateTime.Now 
      }); 

    } 
} 

Repository экземпляр будет введен в обработчик Д.И. контейнера, Ninject в вашем случае.

+0

Я согласен с тем, что содержимое/репозиторий необходимо вводить и не создавать. Однако, что вы получаете от добавления дополнительного уровня абстракции репозитория? В случае, если вам это не понадобится b/c, не будет сразу нескольких технологий доступа к данным «вы только добавили сложности и стоили ничего. В случае, если вы переключите технологии, они будут либо похожи, и поэтому их можно будет легко адаптировать даже без абстракции, иначе они не будут похожи, и в этом случае абстракция только дала вам ложное чувство безопасности (и больше работы и сложности ...) – BatteryBackupUnit

+0

@tsvayer: Я попытался использовать шаблон репозитория, но теперь я нахожусь с той же проблемой, но в классе TransactionRepository. Как я вставляю ObjectContext в этот класс? – Ray

+0

@BatteryBackupUnit, конечно, если у вас есть только десятки обработчиков и еще несколько мест, где вы напрямую обращаетесь к DBContext, нет необходимости в дополнительном уровне абстракции. В зависимости от размера приложения под рукой я бы поставил под сомнение необходимость в контейнере DI. Для использования шаблона DI вам не нужен контейнер. Но в какой-то момент не так просто переключить базовую технологию доступа к данным с помощью сотен обработчиков сообщений в вашем проекте. Другим преимуществом является то, что проще обмануть интерфейс IRepository для модульного тестирования или реализовать поддельный репозиторий в памяти. –