2013-07-15 19 views
9

Bir .Net Web Formları proje yapısı geliştiriyorum ve uygulama için bir DI framework olarak Unity kullanmaya karar verdim. Unity [Depedency] Notu bir bağımlılığın kendisi mi?

MSDN-Resolving in Asp.Net

Projemdeki bağımlılıkları enjekte etmek amacıyla ben DI konteyner ait dışında oluşturulan ilk nesne kurmak gerektiğini belirtmektedir. Bu soruya geldiğimiz söyleniyor. örneğin [Dependency] olarak

  1. özelliği ek açıklamaları Attribute sınıf uzanan sınıflardır. Bunları kullanmak için, bildiren sınıfa başka bir ad alanı eklenmeli ve böylece sınıfımızın Microsoft.Practices.Unity.DependencyAttribute sınıfına bağımlı olması gerekir. Şimdi, sınıfımızın kullandığı IMyInterface'in uygulanmasının farkında olmasa da, Bağımlılık sınıfının somut uygulamasının farkında olmalı mı? Buradaki eksikliğim nedir? DI çerçevesini değiştireceksek, proje boyunca tüm ek açıklamaları kaldırmamız gerekirdi.

  2. Kabın dışında bu tür bildirimlerin (yapılandırma dosyaları veya neyin olmaması) önlenmesi için bir yol var mı?

DÜZENLEME -> Kod burada

/*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; } 
    } 
} 

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")); 

    } 
} 

Ve modül

arkasında

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; 
     } 
    } 
} 

Küresel kod arkasında default.aspx kodu

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; 
     } 
    } 
} 

Modül içindeki kod her seferinde ulaşılır. [Dependency] Özniteliği kullandığımda satır INDEED çalışır.

+2

En IOC konteynerler size kısıtlaması bu tür yerleştirmeyin. Bir soruna neden olursa, alternatif bir kapsayıcıyı düşünebilirsiniz - örn. structuremap, autofac, simpleinjector vb. – MattDavey

+1

Unity Framework'ün bir kısıtı değil, daha çok asp'in bir kısıtı.Nesnelerin Yapısını kontrol edemediğim Net WebForms, bu yüzden Emlak enjeksiyonuna ihtiyacım var. Diğer DI çerçeveleri, söz konusu enjeksiyonu gerektiren sınıfı değiştirmeden Mülkiyet enjeksiyonu yapabilir mi? –

+2

Doğru - bu sorunun ilk cevabı (http://stackoverflow.com/questions/4979453/structuremap-beginner-property-injection) tam olarak bu senaryoyu açıklar (Structuremap kullanarak). DI kütüphanelerinin çoğunun bu davranışı içerdiğini varsayalım. – MattDavey

cevap

5

Evet, Bağımlılık öznitelikleriyle birlikte biber kodu, uygulamayı kapsayıcıya sıkı sıkıya bağlamaktadır.

enjekte etmek hangi özellikleri belirlemeye yönelik birkaç yol vardır:

  • Nitelikler
  • XML Yapılandırma
  • Programlı Yapılandırma
  • Özel konteyner uzantısı etrafında almak için

Tek yön özniteliklerin kullanımı tüm sayfaları kaydetmek ve programsal olarak özellikleri belirlemek BuildUp için gerektiğinde enjekte ve tedarik geçersiz kılmaları için:

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

Sadece bir soru olsa da. BuildUp (Tobject) kullanırsam, kablolama başarılı olur. Bunu http modülümde kullanamıyorum, bu yüzden BuildUp'ı kullanmam gerekiyor (typ (MyPage), myPage); İkincisi, kablolamayı yapmakta başarısız. –

+1

@ThanosK. BuildUp kullanın (myPage.GetType(), myPage); – onof

+0

Aynı şey. Hiçbir kablolama gerçekleşmez –