2012-06-20 65 views
3

我有一個項目,我正在努力,我不知道什麼類我需要在編譯時實例化。我試圖根據用戶輸入使用Activator.CreateInstance()爲我生成一個新類。下面的代碼運行良好,但我不得不將我的INECCQuery類的構造函數更改爲只有默認構造函數,並且不使用任何依賴注入。有沒有辦法我仍然可以使用我的注入綁定和Activator.CreatInstance()?我正在使用Ninject進行注射。Activator.CreateInstance和Ninject

[HttpGet] 
    public ActionResult Index(string item) { 
     Type t = Type.GetType(string.Format("Info.Audit.Query.{0}Query, Info.Audit", item.ToUpper())); 
     if (t != null) { 
     INECCQuery query = (INECCQuery)Activator.CreateInstance(t); 
     var results = query.Check(); 
     return View("Index", results); 
     } 
     return View("Notfound"); 
    } 

回答

3

在可能的情況下始終優先使用構造函數注入,但合適的備份可以利用屬性注入。

http://ninject.codeplex.com/wikipage?title=Injection%20Patterns

class SomeController { 

    [Inject] 
    public Object InjectedProperty { get; set; } 

} 

基礎上您要更換Activator.CreateInstance你可以注入一個Func<T, INECCQuery>或任何廠家要使用的假設。

+0

@zespri,你如何區分'Activator.CreateInstance'和「通過反射構造對象」? –

2

您可以讓Ninject在運行時爲您提供類型爲t的對象,並仍然通過構造函數獲得依賴注入....我在我的應用程序中爲一種情況做了類似的操作。

在的Global.asax.cs文件,我有以下方法:

/// <summary> 
    /// Gets the instance of Type T from the Ninject Kernel 
    /// </summary> 
    /// <typeparam name="T">The Type which is requested</typeparam> 
    /// <returns>An instance of Type T from the Kernel</returns> 
    public static T GetInstance<T>() 
    { 
     return (T)Kernel.Get(typeof(T)); 
    } 

這取決於靜態內核參考。

然後,在代碼中,我做

var myInfrastructureObject = <YourAppNameHere>.GetInstance<MyInfrastructureType>(); 

所以,我知道在編譯時的類型,而你不這樣做,但它不會是很難改變這種狀況。

您也可能希望查看ServiceLocator模式。

0

我已經發現你可以傳入第二個選項到Activator.CreateInstance方法,只要它符合你的構造函數簽名就可以工作。唯一的問題是如果你的參數不匹配你會得到一個運行時錯誤。

Type t = Type.GetType(string.Format("Info.Audit.Query.{0}Query, Info.Audit", item.ToUpper())); 
INECCQuery query = (INECCQuery)Activator.CreateInstance(t, repository); 

感謝您的幫助。