1

При использовании Ninject инъекции собственности следующие работы только если объект инстанцированный в рамках (а не разработчиком в коде), так что инъекции работает:инъекции собственности при инициализации объекта вручную

public class SomeController: Controller { 
    [Inject] 
    public DbContext db {get; set;} 

... 
} 

Однако, когда объект должен быть инстанцирован в коде разработчиком, привязка не происходит (я не хочу сказать, что терпеть неудачу, потому что этого не происходит).

public class DataProvision { 
    [Inject] 
    public DbContext db {get; set;} 

    public List<T> GetList<T>() where T: class, new() { 
     return db.Set<T>().toList(); 
    } 
... 
} 

public class Test { 
    public static void Test(){ 
     DataProvision dp = new DataProvision(); 
     var getValue = dp.GetList<Person>(); 
    } 
} 

Поддерживается ли это даже при поддержке Ninject, и если да, то в чем заключается решение.

Обоснование, почему мы делаем это: переключение между резервными базами данных и активных усилий в БД случае чрезвычайной ситуации

+0

Вот почему вы должны одобрить инъекцию конструктора над инъекцией свойств. Ввод свойств приводит к [Temporal Coupling] (http://blog.ploeh.dk/2011/05/24/DesignSmellTemporalCoupling/), который является дизайнерским запахом. «DataProvision» должен требовать зависимость «DbContext» в своем конструкторе. – Steven

+0

@Steven: Это не имеет никакого значения, потому что в этом случае вам нужно пройти в объекте. Зачем? этот класс DataProvision должен предоставлять DropdownMenues в общем виде в представлениях MVC (он не используется в другом конроллере). Поэтому мы фактически не хотим, чтобы DbContext находился в конструкторе. Однако эта проблема решается путем получения db из ядра, чтобы воспользоваться привязкой. – Arrrr

+0

Вы не должны позволять вашему взгляду иметь какие-либо зависимости. Представления должны быть немыми, и контроллер должен передать все данные, которые требует просмотр. – Steven

ответ

2

Это ожидаемое поведение. Рамка DI не имеет возможности вводить что-либо, если вы new своих собственных экземпляров. Если ваш код имеет доступ к привязкам DI, установить ядро ​​и использовать его, чтобы создать экземпляр класса:

public class Test { 
    public static void Test(){ 
     var kernel = new StandardKernel(new YourDiModule()); 
     DataProvision dp = kernel.Get<DataProvision>(); 
     var getValue = dp.GetList<Person>(); 
    } 
} 

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

В противном случае, Вам необходимо управлять инъекцией зависимостей вручную:

public class Test { 
    public static void Test(){ 
     using (var context = new DbContext()) // or however you create contexts 
     { 
      DataProvision dp = new DataProvision(); 
      dp.db = context; 
      var getValue = dp.GetList<Person>(); 
     } 
    } 
} 
Смежные вопросы