2011-06-20 130 views
3

我有一個業務邏輯組件以下實現一個通用的接口:實例化一個類使用反射

public class BusinessEntity 
{ 
    ... 
} 

public class Customer : BusinessEntity 
{ 
    ... 
} 

public interface IEntityManager <T> where T : BusinessEntity 
{ 
    T SaveData(T oData); 
} 

public CustomerEntityManager : IEntityManager <Customer> 
{ 
    Customer SaveData(Customer o) 
    { 
     ... 
    } 
} 

我不得不來加載上面的組件(由於幾個明顯的原因),在我目前的項目通過反思和實例化CustomersEntityManager。想象一下,我寫的方法如下:

public class EntityFactory 
{ 
    public static IEntityManager<BusinessEntity> GetManagerInstance(string EntityName) 
    { 
    var asm = GetAssembly(); // imagine that I loaded the assembly somehow 
    EntityName = "Customer"; // just imagine 
    object o;  
    // DO NOT KNOW WHAT TO WRITE HERE. 
    return o as IEntityManager<BusinessEntity>; // this needs to be an instance of CustomerEntityManager. 
    } 
} 

我可以選擇修改業務程序集。但實例創建需要在我當前的項目中,我必須使用反射來加載業務程序集。所有的數據類型只有在運行時纔會知道。

我可能會錯過一些根本性的東西,或者可能做錯了編碼。請幫我解決這個問題。

UPDATE:

遵循 「德里斯」 的建議,像以下:

string fullTypeName = "Your.Namespace." + EntityName + "EntityManager"; 
object o = Activator.CreateInstance(asm.FullName, fullTypeName); 

看起來它創建的實例。然而,它結束了一個錯誤:

Cannot cast 'o' (which has an actual type of 'CustomerEntityManager') to 'IEntityManager'

時得到執行以下語句:

return o as IEntityManager<BusinessEntity> 

感謝

回答

3

您需要以某種方式構造完整的類型名稱,以便您可以獲得代表該類型的實例Type。你可能會決定該類型名稱依賴於慣例,這樣你可以找到完整的類型名稱爲:

string fullTypeName = "Your.Namespace." + EntityName + "EntityManager"; 
object o = Activator.CreateInstance(asm.FullName, fullTypeName); 

然後,它僅僅是一個調用Activator.CreateInstance的問題,因爲你看到的。

但是,我強烈建議您考慮使用IoC框架來解決此問題。

回覆:您的評論:

你不能投CustomerEntityManager到IEntityManager,因爲這不是什麼它實現 - 它僅實現IEntityManager。如果允許投票,類型安全性將被破壞(當實施明確期望客戶時,您可以傳入BusinessEntity,或者至少該合同說的是什麼(Co/Contra差異無法將您保存在此,因爲T進出IEntityManager)

+0

+1 for IoC Framework – smartcaveman

+0

driis,我得到錯誤當語句「return o as IEntityManager 」時,無法將'o'(具有'CustomerEntityManager'的實際類型)轉換爲'IEntityManager '正在執行。 – user203687

+0

你不想要IEntityManager ?因爲這是CustomerEntityManager實現的。 – driis

0

結帳Activator.CreateInstance()

Object o = Activator.CreateInstance (asm.FullName, EntityName); 

會給你一個實例的Customer。我不知道你會如何從CustomerCustomerEntity,但我相信你可以完成這一部分。

1

忘記使用自己的低級反射,很多不是很方便的工作,如果可以的話使用IoC框架,例如StructureMap。使用StructureMap,您只需創建一個知道所有依賴項的註冊表(例如CustomersEntityManager就是我們的IEntityManager<Customer>的實現)。它看起來更不像是:

For<IEntityManager<Customer>>().Use<CustomersEntityManager>() 

現在,如果你問你的StructureMap容器​​的IEntityManager<Customer>的實現,你會得到CustomersEntityManager

ObjectFactory.GetInstance<IEntityManager<Customer>>(); // will return instance of CustomersEntityManager 

如果您不知道所請求的類型在編譯時,你可以使用普通的Type實例索要實體管理器:

string entityName = "Customer"; 
Type entityType = Type.GetType(entityType); 
Type requestedType = typeof(IEntityManager<>).MakeGenericType(new[] { entityType }); 
ObjectFactory.GetInstance(requestedType); // will also return CustomersEntityManager instance 

註冊可以在裝配中定義,而不土特產品清商務會議。

+0

感謝您的建議。有沒有Microsoft的PnP實現這樣的? – user203687

+0

是的,它被稱爲Unity - http://msdn.microsoft.com/en-us/library/ff663144.aspx - 它通常應該可以做同樣的事情,但是你必須自己閱讀,因爲我不喜歡我不太瞭解Unity。 – NOtherDev

+0

非常感謝 – user203687

相關問題