2010-03-14 14 views
5

Meine Web-App-Lösung besteht aus drei Projekten:Wie weit erreicht Dependency Injection?

  1. Web App (ASP.NET MVC)
  2. Business Logic Layer (Klassenbibliothek)
  3. Datenbank Layer (Entity Framework)

Ich möchte Ninject verwenden, um die Lebensdauer der DataContext zu verwalten, die von der Entity Framework in der Database Layer generiert wird. Die Business-Logik-Schicht besteht aus Klassen, die auf Repositories verweisen (auf der Datenbank-Ebene), und meine ASP.NET MVC-Anwendung verweist auf die Serviceklassen der Business-Logik-Schicht, um Code auszuführen. Jedes Repository erstellt eine Instanz des MyDataContext Objekt aus dem Entity Framework

Repository

public class MyRepository 
{ 
    private MyDataContext db; 
    public MyRepository 
    { 
     this.db = new MyDataContext(); 
    } 

    // methods 
} 

Business-Logik-Klassen

public class BizLogicClass 
{ 
    private MyRepository repos; 
    public MyRepository 
    { 
      this.repos = new MyRepository(); 
    } 

    // do stuff with the repos 
} 

Will Ninject die Lebensdauer von MyDataContext trotz der langen Abhängigkeitskette aus dem Web umgehen App auf die Datenschicht?

Antwort

3

EDIT

I hat einige Probleme mit ihm vor einiger Zeit, aber jetzt scheint es zu funktionieren:

Bind<CamelTrapEntities>().To<CamelTrapEntities>().Using<OnePerRequestBehavior>(); 

Statt Httpmodule zu verwenden, können Sie OnePerRequestBehavior verwenden und es kümmert sich um Kontext in aktueller Anfrage behandeln.

EDIT 2

OnePerRequestBehavior in web.config werden muss registriert, weil sie zu sehr auf Httpmodule abhängt:

In IIS6:

<system.web> 
    <httpModules> 
    <add name="OnePerRequestModule" type="Ninject.Core.Behavior.OnePerRequestModule, Ninject.Core"/> 
    </httpModules> 
</system.web> 

Mit IIS7:

<system.webServer> 
    <modules> 
    <add name="OnePerRequestModule" type="Ninject.Core.Behavior.OnePerRequestModule, Ninject.Core"/> 
    </modules> 
</system.webServer> 

VORHERIGE ANTWORT

Es liegt in Ihrer Verantwortung, den Kontext zu entsorgen, wenn er nicht benötigt wird. Am häufigsten wird in ASP.NET ein ObjectContext pro Anfrage verwendet. Ich tue es, indem Httpmodule:

public class CamelTrapEntitiesHttpModule : IHttpModule 
{ 
    public void Init(HttpApplication application) 
    { 
     application.BeginRequest += ApplicationBeginRequest; 
     application.EndRequest += ApplicationEndRequest; 
    } 

    private void ApplicationEndRequest(object sender, EventArgs e) 
    { 
     ((CamelTrapEntities) HttpContext.Current.Items[@"CamelTrapEntities"]).Dispose(); 
    } 

    private static void ApplicationBeginRequest(Object source, EventArgs e) 
    { 
     HttpContext.Current.Items[@"CamelTrapEntities"] = new CamelTrapEntities();    
    } 
} 

Dies ist Injektion Regel:

Bind<CamelTrapEntities>().ToMethod(c => (CamelTrapEntities) HttpContext.Current.Items[@"CamelTrapEntities"]); 

Mein Repository nimmt Object in Konstruktor:

public Repository(CamelTrapEntities ctx) 
{ 
    _ctx = ctx; 
} 
+0

Was bedeutet „scheint zu funktionieren“? – jfar

+0

@jfar: Ich habe es vor ein paar Augenblicken überprüft und kernel.Get <> zweimal aufgerufen, gab mir dieselbe Instanz in der Anfrage. Ich erinnere mich nicht genau, was die Probleme vorher waren, aber irgendwie entschied ich mich, es nicht zu verwenden. In der Zwischenzeit habe ich neue Quellen heruntergeladen, aber bis heute nicht überprüft, also wurde es wahrscheinlich korrigiert. – LukLed

3

Ich will nur erwähnen, dass Autofac with the ASP.Net integration die Anfrage Lebensdauer haben Unterstützung eingebaut.Beheben Sie Instanzen in der RequestContainer, und sie werden am Ende der Anfrage entsorgt (wenn IDisposable implementiert wird).

Sie sollten Ihre Klassen DI freundlich obwohl machen:

public class MyRepository 
{ 
    private MyDataContext db; 
    public MyRepository(MyDataContext context) 
    { 
     this.db = context; 
    } 

    // methods 
} 

public class BizLogicClass 
{ 
    private MyRepository repos; 
    public BizLogicClass(MyRepository repository) 
    { 
      this.repos = repository; 
    } 

    // do stuff with the repos 
}