2009-05-24 28 views
5

我編寫了一些C#類庫文件,我想使用Ninject爲我的類提供依賴注入。 class libary是否有可能聲明一些代碼(方法),這些代碼將在類庫libary被加載時執行。我需要這個來定義Ninject的綁定。加載程序集後執行的C#方法

回答

1

我在過去9個月中使用了Ninject。聽起來你需要做的是將存在於你的libray中的模塊「加載」到Ninject內核中,以便註冊綁定。

我不確定您是否使用Ninject 1.x或2.0測試版。這兩個版本的表現略有不同,但從概念上講,它們是相同的。我將堅持使用1.x版進行討論。我不知道的另一條信息是,如果你的主程序正在實例化Ninject內核,並且你的庫只是簡單地向該內核添加綁定,或者你的庫本身包含內核和綁定。我假設您需要將庫中的綁定添加到主程序集中的現有Ninject內核中。最後,我將假設您正在動態加載這個庫,並且它沒有靜態鏈接到主程序。

要做的第一件事是在庫中定義一個ninject模塊,在其中註冊所有綁定 - 您可能已經完成了此操作,但值得一提。例如:

public class MyLibraryModule : StandardModule { 
    public override void Load() { 
    Bind<IMyService>() 
     .To<ServiceImpl>(); 
    // ... more bindings ... 
    } 
} 

既然您的綁定包含在Ninject模塊中,您可以在加載程序集時輕鬆註冊它們。這個想法是,一旦你加載你的程序集,你可以掃描所有從StandardModule派生的類型。一旦你有這些類型,你可以將它們加載到內核中。

// Somewhere, you define the kernel... 
var kernel = new StandardKernel(); 

// ... then elsewhere, load your library and load the modules in it ... 

var myLib = Assembly.Load("MyLibrary"); 
var stdModuleTypes = myLib 
         .GetExportedTypes() 
         .Where(t => typeof(StandardModule).IsAssignableFrom(t)); 


foreach (Type type in stdModuleTypes) { 
    kernel.Load((StandardModule)Activator.CreateInstance(type)); 
} 

有一點需要注意,您可以進一步概括上述代碼以加載多個庫並註冊多個類型。另外,正如我上面提到的,Ninject 2具有內置的這種能力 - 它實際上具有掃描目錄,加載程序集和註冊模塊的能力。很酷。

如果您的方案與我所概述的略有不同,可能會對類似的原則進行調整。

6

這聽起來像你正在尋找相當於C++的DllMain。在C#中沒有辦法做到這一點。

你能給我們提供一些關於你的場景的更多信息,以及爲什麼你需要在DllMain樣式函數中執行代碼?

在類型上定義靜態構造函數並不能解決此問題。只有在以任何方式使用類型本身之前,才能保證運行靜態類型構造函數。你可以定義一個靜態構造函數,在Dll中使用其他代碼,它不會訪問該類型,它的構造函數永遠不會運行。

-1

據我所知,答案是 。據我所知,你想在你的類庫中配置你的IoC容器,如果是這樣的話,這不是一個好主意。如果你在你的定義綁定類庫那麼什麼是依賴注入的用法?我們使用依賴注入,以便我們可以在運行時注入依賴關係,然後我們可以在不同的場景中注入不同的對象。儘管配置IoC容器的最佳位置是應用程序的啓動(因爲IoC容器就像應用程序的主幹:)),但它應該放置在負責啓動應用程序的引導程序中。在簡單的應用程序中,它可以是Main方法。

+0

在很多情況下,您想要在類庫中定義綁定。您可能會在不同的庫中具有不同的相同服務實現,這兩種實現可能基於服務使用的上下文同時在同一應用程序中相關。 Ninject(與其他IoC一樣)提供定義上下文綁定的能力,因此能夠根據某些提供的上下文激活不同的具體服務。 – 2009-05-27 03:24:47

0

你能控制客戶端代碼嗎?如果是的話,我不會在加載程序集時嘗試使用魔法,而是會執行一個像註冊表一樣的單個類來執行綁定,實現一個接口IRegistry。然後在加載過程中,您可以在組件中查找IRegistry的實現並激發必要的方法。

你也可以擁有屬性上你的類:

[Component(Implements=typeof(IMyDependency)] 

看看這些屬性並將其加載到客戶端的容器。

或者你可以看看MEF這是一個圖書館這種情況。

1

您是否嘗試過AppDomain.AssemblyLoad事件?它在裝配完成後觸發。

AppDomain.CurrentDomain.AssemblyLoad += (s, e) => 
{ 
    Assembly justLoaded = e.LoadedAssembly; 
    // ... etc. 
}; 
相關問題