Ответ 1
Поскольку вы используете NinjectWebCommon
, я предполагаю, что у вас есть какое-то веб-приложение. Вам действительно нужно получить доступ к ядру Ninject в одном месте - в корневой каталог. Это место, где вы строите графический объект и единственное место, где вам когда-либо понадобится доступ к контейнеру IoC. Чтобы получить нужные зависимости, вы обычно используете впрыск конструктора.
В случае веб-приложений MVC, например, у вас есть контроллер factory с использованием ядра Ninject и единственное место, которое ссылается на него.
Чтобы расширить вашу конкретную ситуацию, ваш класс примет ICustomerBusiness
в своем конструкторе, объявив, что ему нужен экземпляр ICustomerBusiness
как его зависимость:
class CustomerBusinessConsumer : ICustomerBusinessConsumer
{
private readonly ICustomerBusiness customerBusiness;
public CustomerBusinessConsumer(ICustomerBusiness customerBusiness)
{
this.customerBusiness = customerBusiness;
}
...
}
Теперь, в зависимости от того, какой класс использует ICustomerBusinessConsumer
в качестве своей зависимости, будет следовать один и тот же шаблон (принимающий экземпляр ICustomerBusinessConsumer
в качестве его параметра конструктора). В основном никогда не создавайте свои зависимости вручную, используя new
(в некоторых случаях исключения).
Затем вам нужно только убедиться, что ваши классы получают свои зависимости, и это этот корневой состав, где вы это делаете. То, что именно является составным корнем, зависит от типа приложения, которое вы пишете (консольное приложение, приложение WPF, веб-сервис, веб-приложение MVC...)
ИЗМЕНИТЬ. Чтобы ознакомиться с ситуацией в области ASP.NET WebForms Мне пришлось искать детали, потому что я никогда не использовал его. К сожалению, WebForms требует, чтобы у вас был произвольный конструктор на каждом из ваших классов страниц, поэтому вы не можете использовать инсталляцию конструктора полностью из верхней части графика объекта вниз.
Однако, после консультации с Mark Seeman о создании объектов в WebForms, я могу перефразировать, как бороться с этой неэффективностью системы, но все еще действуя в линии с хорошими практиками DI:
-
Имейте класс, ответственный за разрешение зависимостей, используя установленное вами ядро Ninject. Это может быть очень тонкая оболочка вокруг ядра. Позвольте называть его
DependencyContainer
. -
Создайте свой контейнер и сохраните его в контексте приложения, чтобы он был готов, когда вам это нужно
protected void Application_Start(object sender, EventArgs e) { this.Application["container"] = new DependencyContainer(); }
-
Предположим, что ваш класс страницы (пусть называется
HomePage
) имеет зависимость отICustomerBusinessConsumer
. ТогдаDependencyContainer
должно позволить нам получить экземплярICustomerBusinessConsumer
:public ICustomerBusinessConsumer ResolveCustomerBusinessConsumer() { return Kernel.Get<ICustomerBusinessConsumer>(); }
-
Чем в самом классе
MainPage
вы разрешите его зависимости в конструкторе по умолчанию:public MainPage() { var container = (DependencyContainer) HttpContext.Current.Application["container"]; this.customerBusinessConsumer = container.ResolveCustomerBusinessConsumer(); }
Несколько заметок:
-
наличие контейнера зависимостей, доступного в
HttpContext
, не должно заманчиво рассматривать его как локатор службы. Фактически, лучшая практика здесь (по крайней мере, с точки зрения истины DI) заключается в том, чтобы иметь какие-то "классы-разработчики", к которым вы будете передавать функциональность своих классов страниц.Например, каждое действие, обработанное
MainPage
, будет передано только его классу-разработчику. Этот класс-реализатор будет зависеть отMainPage
и, как и все другие зависимости, будет разрешен с использованием контейнера.Важная роль заключается в том, что эти классы-разработчики должны быть в сборках, не ссылающихся на сборки ASP.NET и, таким образом, без возможности доступа к
HttpContext
-
чтобы написать столько кода для достижения этого, конечно, не идеально, но это только следствие ограничения рамки. Например, в приложениях ASP.NET MVC это рассматривается намного лучше. Там у вас есть одна точка, где вы можете составлять графы объектов, и вам не нужно разрешать их в каждом классе верхнего уровня, как это необходимо в WebForms.
-
Хорошо, что, хотя вам нужно написать некоторый сантехнический код в конструкторах класса страниц, оттуда вниз по графу объектов вы можете использовать конструкторскую инъекцию