Weder die Page-Klasse noch die Präsentatoren sollten direkt mit der Verwaltung der Konstruktion oder des Lebenszyklus von Abhängigkeiten zu tun haben - dies sollte alles von Ihrem Container gehandhabt werden. Da die Konstruktorinjektion nicht mit WebForms funktioniert, müssen Sie alle erforderlichen Abhängigkeiten als Eigenschaften für die Klasse verfügbar machen. Zum Beispiel könnten Sie Ihre Klasse ändern:
public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
}
public _DefaultPresenter Presenter { get; set; }
}
Die Seite sollte jede Bezugnahme auf das Repository nicht benötigen, wie es in den Präsentator injiziert wird.
Der Rest dieser Antwort ist spezifisch für StructureMap - Details können für andere Container abweichen.
Um die Setter-Injektion zu aktivieren, müssen Sie StructureMap mitteilen, welche Eigenschaften aufgefüllt werden sollen. Eine Möglichkeit besteht darin, das Attribut [SetterProperty] auf die Eigenschaft selbst anzuwenden. Dies kann jedoch ein wenig aufdringlich wirken, wenn Sie StructureMap-Details in Ihren Klassen verwenden möchten. Eine andere Möglichkeit besteht darin, StructureMap so zu konfigurieren, dass es weiß, welche Eigenschaftentypen injiziert werden sollen. Zum Beispiel:
protected void Application_Start(object sender, EventArgs e)
{
ObjectFactory.Initialize(x =>
{
x.Scan(scan =>
{
scan.TheCallingAssembly();
scan.WithDefaultConventions();
});
x.ForRequestedType<IRepository>().TheDefaultIsConcreteType<Repository>().CacheBy(InstanceScope.Hybrid);
x.SetAllProperties(set => set.WithAnyTypeFromNamespaceContainingType<IRepository>());
});
}
Die SetAllProperties Methode ermöglicht es Ihnen StructureMap zu sagen, wie die Eigenschaften zu erkennen, sollte es füllen. In diesem Fall rate ich StructureMap, alle Präsentatoren zu injizieren (vorausgesetzt, sie befinden sich alle im selben Namensraum).
Sie müssen die Setter-Injektion bei jeder Anforderung noch durchführen.Mit StructureMap verwenden Sie die BuildUp() -Methode, um Abhängigkeiten in eine vorhandene Instanz einzufügen. Sie könnten dies in den Init- oder Load-Ereignissen jeder Seite oder in einer Seitenbasisklasse tun, aber auch das fühlt sich invasiv an. Um den Behälter zu halten vollständig aus Ihrer Seite Klassen, können Sie die PreRequestHandlerExecute Ereignis der Anwendung (in global.asax oder eine IHttpModule):
protected void Application_PreRequestHandlerExecute(object sender, EventArgs e)
{
var application = (HttpApplication)sender;
var page = application.Context.CurrentHandler as Page;
if (page == null) return;
ObjectFactory.BuildUp(page);
}
Schließlich, wenn Sie möchten ausdrücklich Entsorgen Sie Ihre IRepository, Sie dass in der Endrequest-Ereignis behandeln könnte:
protected void Application_EndRequest(object sender, EventArgs e)
{
var disposable = ObjectFactory.GetInstance<IRepository>() as IDisposable;
if (disposable != null) disposable.Dispose();
}
Beachten Sie, dass dies funktioniert, weil in der Initialisierung wir StructureMap sagte IRepository von Hybrid zwischenzuspeichern, die für jede HTTP-Request (oder Thread „Gib mir die gleiche Instanz bedeutet, wenn nicht innerhalb einer Website läuft) ". Wenn Sie das IRepository in EndRequest abrufen, erhalten Sie dasselbe, das während der gesamten Anfrage verwendet wurde, und Sie können es entsorgen.
Entschuldigung, dass Sie den Code oder die Tags in Ihrer Frage nicht angesehen haben! Habe es jetzt überarbeitet - hoffe das verbessert die Sache! Wird dies löschen, wenn Sie Ihre löschen ... –