Мой код будет ссылаться на Microsoft Unity, но я уверен, что он довольно применим ко всем структурам DI. Если вы используете DI правильно, вам никогда не нужно вызывать новый BusinessObject (новый dataContext), ассоциация DI будет обрабатывать все это за вас.
Мой пример будет немного длиннее, так как я вставлю код, который я использую для запуска сайта Model View Presenter, полностью загруженного Unity. (Если вы хотите получить полный исходный код, просмотрите мой блог и загрузите его с моего SVN-сервера Assembla)
Загрузить контейнер (может быть в коде, как я предпочитаю, или использовать конфигурацию)
protected void Application_Start(object sender, EventArgs e)
{
Application.GetContainer()
// presenters / controllers are per request
.RegisterType<IEmployeeController, EmployeeController>(new ContextLifetimeManager<IEmployeeController>())
//Data Providers are Per session
.RegisterType<IEmployeeDataProvider, EmployeeDataProvider>(new SessionLifetimeManager<IEmployeeDataProvider>())
//Session Factory is life time
.RegisterType<INHibernateSessionManager, NHibernateSessionManager>(new ContainerControlledLifetimeManager());
}
Пользовательский модуль HTTP вызывает метод Unity BuildUp для каждой страницы во время вызова OnPreRequest.
private static void OnPreRequestHandlerExecute(object sender, EventArgs e)
{
var handler = HttpContext.Current.Handler;
HttpContext.Current.Application.GetContainer().BuildUp(handler.GetType(), handler);
// User Controls are ready to be built up after the page initialization is complete
var page = HttpContext.Current.Handler as Page;
if (page != null)
{
page.InitComplete += OnPageInitComplete;
}
}
Ведущий контейнера страницы, украшенный атрибутом [Dependency]
public partial class Employees : Page, IEmployeeView
{
private EmployeePresenter _presenter;
[Dependency]
public EmployeePresenter Presenter
{
set
{
_presenter = value;
_presenter.View = this;
}
}
}
Ведущий с методом InjectionConstructor
public class EmployeePresenter : Presenter<IEmployeeView>
{
private readonly IEmployeeController _controller;
[InjectionConstructor]
}
public EmployeePresenter(IEmployeeController controller)
{
_controller = controller;
}
Контроллер следует за костюмом
public class EmployeeController : IEmployeeController
{
private readonly IEmployeeDataProvider _provider;
[InjectionConstructor]
public EmployeeController(IEmployeeDataProvider DataProvider)
{
_provider = DataProvider;
}
}
То же с провайдером
public class EmployeeController : IEmployeeController
{
private readonly IEmployeeDataProvider _provider;
[InjectionConstructor]
public EmployeeController(IEmployeeDataProvider DataProvider)
{
_provider = DataProvider;
}
}
Наконец, менеджер сеансов, который содержит только обычный конструктор.
public class NHibernateSessionManager : INHibernateSessionManager
{
private readonly ISessionFactory _sessionFactory;
public NHibernateSessionManager()
{
_sessionFactory = GetSessionFactory();
}
}
Так что же происходит, когда запускается запрос страницы, метод BuildUp () вызывается на странице HttpModule. Затем Unity увидит Свойство, помеченное атрибутом Dependency, и проверит его контейнер, чтобы увидеть, существует ли внутри него объект EmployeePresenter.
Поскольку такого объекта в контейнере нет, он попытается создать EmployeePresenter. После проверки, чтобы создать класс, который он видит внутри Presenter, ему нужен конструктор, которому нужен IEmployeeController, внедренный в него. Поскольку у контейнера действительно есть диспетчер для контроллера, он увидит, существует ли его экземпляр в контейнере, которого в начале запроса страницы не существует, поэтому он перейдет к созданию экземпляра контроллера.
Затем Unity увидит, что контроллеру требуется вставленный в него IEmployeeDataProvider, и он продолжит этот процесс до тех пор, пока, наконец, не достигнет точки, когда провайдеру понадобится внедрить менеджер сеансов. Поскольку диспетчер сеансов больше не нуждается в инъекции, Unity затем создаст экземпляр диспетчера сеансов, сохранит его в контейнере, для которого ему задан ContainerLifeTimeManager, внедрит его в провайдера и сохранит этот экземпляр, и так далее, где он завершил создание Зависимость EmployeePresenter для страницы.