2013-07-15 7 views
9

Ich entwickle eine .Net Web Forms-Projektstruktur und entschied mich, Unity als DI-Framework für die Anwendung zu verwenden.Ist nicht Unity [Depetency] Annotation eine Abhängigkeit selbst?

MSDN-Resolving in Asp.Net besagt, dass, um Abhängigkeiten in meinem Projekt zu injizieren ich müssen das anfängliche Objekt aufzubauen, dieaußerhalb des DI-Container erstellt wird. Davon abgesehen kommen wir zu der Frage.

  1. Die Attribut Annotationen wie [Dependency] Klassen sind die Klasse Attribute erstreckt. Um sie zu verwenden, muss ein anderer Namensraum in der deklarierenden Klasse enthalten sein, was unsere Klasse von der Klasse Microsoft.Practices.Unity.DependencyAttribute abhängig macht. Nun, obwohl unsere Klasse die Implementierung von IMyInterface, die sie verwendet, nicht kennt, muss sie sich der konkreten Implementierung der Dependency-Klasse bewusst sein? Was fehlt mir hier? Wenn wir das DI-Framework ändern würden, müssten wir alle Anmerkungen im gesamten Projekt entfernen.

  2. Gibt es eine Möglichkeit, diese Art der Deklaration (Konfigurationsdateien oder was nicht?) Außerhalb des Containers zu vermeiden?

EDIT -> Code-hier

/*This is the abstract base class where I want the dependency injection to occur*/ 
public abstract class BasePage : System.Web.UI.Page 
{ 
    private IMyService _dtService; 
    public IMyService DtService 
    { 
     get { return _dtService; } 
     set { _dtService = value; } 
    } 
} 

Der Default.aspx Code hinter

public partial class _Default : BasePage 
{ 

    public _Default() 
    { 

    } 

    protected void Page_Load(object sender, EventArgs e) 
    { 
     try 
     { 
      DataClass dt = DtService.GetDataById(2); 
      lblWhatever.Text = dt.Description; 
     } 
    } 
} 

Global code hinter

public class Global : System.Web.HttpApplication 
{ 
    void Application_Start(object sender, EventArgs e) 
    { 
     IUnityContainer myContainer = HttpContext.Current.Application.GetDIContainer(); 
     myContainer.RegisterType<IMyService,MyServiceClient>(new 
        InjectionConstructor("MyServiceWsEndpoint")); 
     // I have tried this with BasePage too 
     myContainer.RegisterType<_Default>(new InjectionProperty("DtService")); 

    } 
} 

und das Modul

public class UnityHttpModule : IHttpModule 
{ 
    public void Init(HttpApplication context) 
    { 
     context.PreRequestHandlerExecute += OnPreRequestHandlerExecute; 
    } 

    public void Dispose() { } 

    private void OnPreRequestHandlerExecute(object sender, EventArgs e) 
    { 
     IHttpHandler currentHandler = HttpContext.Current.Handler; 
     /*This does not work*/ 
HttpApplicationStateExtensions.GetDIContainer(HttpContext.Current.Application).BuildUp(
          currentHandler.GetType(), currentHandler); 
     /* While this works*/ 
HttpApplicationStateExtensions.GetDIContainer(HttpContext.Current.Application).BuildUp<_Default>((_Default)currentHandler); 

     var currentPage = HttpContext.Current.Handler as Page; 
     if (currentPage != null) 
     { 
      currentPage.InitComplete += OnPageInitComplete; 
     } 
    } 
} 

Der Code im Modul wird jedes Mal erreicht. Die Zeile funktioniert, wenn ich das [Dependency] Attribut verwende.

+2

meist IOC-Container stellen Sie nicht diese Art von Einschränkung für Sie. Wenn es ein Problem verursacht, könnten Sie einen alternativen Container in Betracht ziehen - z. Strukturkarte, Autofac, Simeinjector etc. – MattDavey

+1

Es ist nicht so sehr eine Einschränkung des Unity Framework, es ist eher eine Einschränkung der asp.Net WebForms, wo ich die Konstruktion der Objekte nicht kontrollieren kann, also muss ich Property injection machen. Diese anderen DI-Frameworks können Property-Injection durchführen, ohne die Klasse zu ändern, die diese Injektion benötigt? –

+2

Das stimmt - die erste Antwort auf [diese Frage] (http://stackoverflow.com/questions/4979453/structemap-beginner-property-injection) beschreibt genau dieses Szenario (unter Verwendung von Structuremap). Ich nehme an, dass die meisten DI-Bibliotheken dieses Verhalten enthalten. – MattDavey

Antwort

5

Ja, Peppering-Code mit Abhängigkeitsattributen verbindet die Implementierung eng mit dem Container.

Es gibt ein paar Möglichkeiten, um zu bestimmen, welche Eigenschaften zu injizieren:

  • Attribute
  • XML-Konfiguration
  • Programmatische Konfiguration
  • Benutzerdefinierte Behältererweiterung

Ein Weg, um zu bekommen Die Verwendung von Attributen besteht darin, alle Seiten zu registrieren und programmatisch die Eigenschaften anzugeben je nach Bedarf zu injizieren und Versorgungsüberschreibungen BuildUp:

IUnityContainer container = new UnityContainer(); 

// Assume we have a logger we are injecting 
container.RegisterType<ILogger, Logger>(new ContainerControlledLifetimeManager()); 

// Register the Dependency Properties for the Page 'MyPage'. 
// Property names on MyPage are "Logger" 
container.RegisterType<MyPage>(new InjectionProperty("Logger")); 

// ...later 

IHttpHandler currentHandler = HttpContext.Current.Handler; 

// Perform Property Injection. 
// Logger will be injected from the existing container registration. 
container.BuildUp(currentHandler.GetType(), currentHandler); 
+0

Nur eine Frage. Wenn ich BuildUp (Tobject) verwende, ist die Verkabelung erfolgreich. Ich kann diesen jedoch nicht in meinem HTTP-Modul verwenden, daher muss ich BuildUp verwenden (typeof (MyPage), myPage); Der zweite versagt bei der Verkabelung. –

+1

@ ThanosK. Verwenden Sie BuildUp (myPage.GetType(), myPage); – onof

+0

Das Gleiche. Keine Verkabelung erfolgt –

Verwandte Themen