Mein Code wird sich auf Microsoft Unity beziehen, aber ich bin mir sicher, dass er auf alle DI-Frameworks anwendbar ist. Wenn Sie DI richtig einsetzen, brauchen Sie nie new BusinessObject(new dataContext) aufzurufen, da die DI-Assoziation alles für Sie erledigt.
Mein Beispiel wird ein wenig lang sein, da ich einige Codes einfügen werde, die ich zum Ausführen einer Model View Presenter-Website verwende, die vollständig von Unity geladen wird. (Wenn Sie den vollständigen Quellcode wollen, besuchen Sie meinen Blog und laden Sie ihn von meinem Assembla SVN-Server herunter)
Laden des Containers (kann im Code erfolgen, wie ich es bevorzuge, oder über die Konfiguration)
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());
}
Das benutzerdefinierte HTTP-Modul ruft die Unity BuildUp-Methode für jede Seite während des OnPreRequest-Aufrufs auf.
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;
}
}
Seitencontainer-Präsenter mit dem Attribut [Abhängigkeit] verziert
public partial class Employees : Page, IEmployeeView
{
private EmployeePresenter _presenter;
[Dependency]
public EmployeePresenter Presenter
{
set
{
_presenter = value;
_presenter.View = this;
}
}
}
Presenter mit InjectionConstructor-Methode
public class EmployeePresenter : Presenter<IEmployeeView>
{
private readonly IEmployeeController _controller;
[InjectionConstructor]
}
public EmployeePresenter(IEmployeeController controller)
{
_controller = controller;
}
Controller folgt dem Beispiel
public class EmployeeController : IEmployeeController
{
private readonly IEmployeeDataProvider _provider;
[InjectionConstructor]
public EmployeeController(IEmployeeDataProvider DataProvider)
{
_provider = DataProvider;
}
}
Dasselbe gilt für Anbieter
public class EmployeeController : IEmployeeController
{
private readonly IEmployeeDataProvider _provider;
[InjectionConstructor]
public EmployeeController(IEmployeeDataProvider DataProvider)
{
_provider = DataProvider;
}
}
Und schließlich der Sitzungsmanager, der nur einen regulären Konstruktor enthält.
public class NHibernateSessionManager : INHibernateSessionManager
{
private readonly ISessionFactory _sessionFactory;
public NHibernateSessionManager()
{
_sessionFactory = GetSessionFactory();
}
}
Wenn also eine Seitenanforderung gestartet wird, wird die BuildUp()-Methode auf der Seite durch das HttpModul aufgerufen. Unity sieht dann die mit dem Attribut Dependency markierte Eigenschaft und überprüft ihren Container, um zu sehen, ob darin ein EmployeePresenter-Objekt existiert.
Da sich kein solches Objekt im Container befindet, wird er versuchen, einen EmployeePresenter zu erstellen. Bei der Inspektion zur Erstellung der Klasse sieht er, dass innerhalb des Presenters ein Konstruktor erforderlich ist, der einen IEmployeeController benötigt, der in ihn injiziert wird. Da der Container tatsächlich einen Manager für den Controller hat, wird er sehen, ob eine Instanz davon im Container existiert, die zu Beginn der Seitenanforderung nicht existiert, also wird er gehen, um den Controller zu instanzieren.
Unity sieht dann, dass der Controller einen IEmployeeDataProvider benötigt, der in ihn injiziert wird, und setzt diesen Prozess fort, bis er schließlich zu dem Punkt gelangt, an dem der Provider den Sitzungsmanager injiziert haben muss. Da der Sitzungsmanager keine Injektion mehr benötigt, erstellt Unity eine Instanz des Sitzungsmanagers, speichert sie im Container für den gegebenen ContainerLifeTimeManager, injiziert sie in den Provider und speichert diese Instanz, und so weiter bis zu dem Punkt, an dem die Erstellung einer EmployeePresenter-Abhängigkeit für die Seite abgeschlossen ist.