2015-03-10 2 views
0

Допустим, у меня есть следующие модели:Dependency Injection для извлечения объекта из Entity Framework

public class Dojo 
{ 
    public int DojoId {get;set;} 
    public DojoProperty PropOne{get;protected set;} 
    public DojoProperty PropTwo{ get;protected set; } 
    public virtual ICollection<ISamurai> Warriors { get; set; } 
    private IDojoService _dojoService; 
    public Dojo(IDojoService dojoService) 
    { 
     _dojoService = dojoService; 
    } 
} 

Я использую последнюю Ninject для DI и хотите иметь фабричный метод, а также осуществить последнюю версию Entity рамки для ОРМ, так что я реорганизовать класс следующим образом:

public class Dojo 
{ 
    public int DojoId {get;set;} 
    public DojoProperty PropOne{get;protected set;} 
    public DojoProperty PropTwo{ get;protected set; } 
    public virtual ICollection<ISamurai> Warriors { get; set; } 
    private IDojoService _dojoService; 
    private Dojo(IDojoService dojoService) 
    { 
     _dojoService = dojoService; 
    } 
    public static Dojo Create(IDojoService dojoService, IDojoConfig dojoConfig) 
    { 
     return new Dojo(dojoService) {PropOne = dojoConfig.PropOne, PropTwo = dojoConfig.PropTwo}; 
    } 
} 

Мой вопрос, как я могу получить Entity Framework, чтобы использовать контейнер IoC, чтобы впрыснуть IDojoService когда я извлечь Dojo из т.е. базы данных:

context.Dojos.Find(dojoId); 
+3

Мой совет: не делать инъекции конструктора (или впрыскивание свойств) в ваших сущностях: https://stackoverflow.com/questions/28715966/entity-framework-object-materialization-and-dependency-injection – Steven

+0

Большое спасибо за ваш комментарий @Steven. Если бы вы взглянули на мой ответ и посмотрели, лучше ли это, чем вопрос. Если у вас есть лучший ответ, я с радостью соглашусь на мое, особенно если я пропустил некоторые ключевые сведения. – ChrisT

ответ

0

Так комментарий Стивен привел меня сделать много полезного чтения, в частности, статью из его (я полагаю?) https://www.cuttingedge.it/blogs/steven/pivot/entry.php?id=91

На первый я неправильно его подход, оригинальный ответ ниже.

Мой новый ответ, основанный на его последнем комментарий:
Использование первых:

public void AddWarrior(int dojoId, ISamurai warrior) 
    { 
     var command = new AddWarriorCommand {DojoId = dojoId, Warrior = warrior}; 
     handler.Handle(command); 
    } 

Больше глубины на AddWarriorCommandHandler:

public class AddWarriorCommandHandler : ICommandHandler<AddWarriorCommand> 
{ 
    //ommitted ctor bringing in dependencies (e.g. Repository) 
    public void Handle(AddWarriorCommand command) 
    { 
      var dojo = context.Dojos.Find(command.dojoId); 
      dojo.Warriors.Add(command.Warrior); 
      context.SaveChanges(); 
    } 
} 

Новая модель:

public class Dojo 
{ 
    public int DojoId { get; set;} 
    public DojoProperty PropOne { get; protected set;} 
    public DojoProperty PropTwo{ get; protected set; } 
    public virtual ICollection<ISamurai> Warriors { get; set; } 

    private Dojo(){} 

    public static Dojo Create(IDojoConfig dojoConfig) 
    { 
     return new Dojo() {PropOne = dojoConfig.PropOne, PropTwo = dojoConfig.PropTwo}; 
    } 
} 

Старого ответ для потомков: Это привело меня интерпретировать следующий подход, который помогает предотвратить анемию модели домена я пытался избежать, держит контейнер IoC и ORM счастливыми и фактически улучшает общую солидность, проверяемость и другие преимущества, изложенные в его статье.

public class Dojo 
{ 
    public int DojoId { get; set;} 
    public DojoProperty PropOne { get; protected set;} 
    public DojoProperty PropTwo{ get; protected set; } 
    public virtual ICollection<ISamurai> Warriors { get; set; } 

    private Dojo(){} 

    public static Dojo Create(IDojoConfig dojoConfig) 
    { 
     return new Dojo() {PropOne = dojoConfig.PropOne, PropTwo = dojoConfig.PropTwo}; 
    } 

    public void AddWarrior(ICommandHandler<AddWarriorCommand> handler, ISamurai warrior) 
    { 
     var command = new AddWarriorCommand {Warrior = warrior}; 
     handler.Handle(command); 
    } 
} 

И тогда использование:

var dojo = context.Dojos.Find(dojoId); 
dojo.AddWarior(handler, new Warrior()); 

С AddWarriorCommand : ICommand и ICommandHandler, определенной согласно статье, а последний вводится в зависимую класс с Ninject

+0

Это интересный подход, но не общий для людей, которые используют обработчики команд в сочетании с DDD. Вместо этого более обычным является инвертирование зависимостей, и пусть обработчик команды вызывает методы воина. Другими словами: уровень представления выполняет команду, а обработчик команд загружает одно или несколько объектов и вызывает метод домена на них. пс. Да, эта статья моя. – Steven

+0

Большое спасибо @Steven Я обновил ваш последний комментарий. Я * думаю * Я понял это сейчас. Ваше руководство очень ценится – ChrisT