2013-04-17 45 views
2

我在我的ASP.NET MVC應用程序中有一個接口/類,其中引用了所有我的通用存儲庫。這看起來是這樣的:在C#中使用反射和泛型屬性

public interface IDb 
{ 
    IGenericRepository<Car> CarRepository { get; } 
    ... 
    IGenericRepository<User> UserRepository { get; } 
} 

我的目標是找到一個組件,它實現一定的接口,然後找到相應的通用存儲庫從數據庫中獲取某些對象的所有類型。這應該工作:

List<IVehicle> vehicleElements = new List<IVehicle>(); 

Type vehicleType = typeof(IVehicle); 
Type dbType = typeof(IDb); 
foreach (Type type in vehicleType.Assembly.GetTypes().Where(t => t.IsClass && t.GetInterfaces().Contains(vehicleType))) 
    { 
     PropertyInfo repositoryInfo = dbType.GetProperties().Where(p => p.PropertyType.GenericTypeArguments.Contains(type)).SingleOrDefault(); 
     if (repositoryInfo != null) 
     { 
      var repository = repositoryInfo.GetValue(this.db); 
      // TODO: work with repository 
     } 
    } 

return vehicleElements; 

我的問題是,我不知道如何將資源庫變量轉換爲所需要的通用IGenericRepository ...任何想法?

+2

你可以創建一個非泛型的'IRepository'並且(轉換爲和)與它一起工作。 –

+1

您可以使用'dynamic'關鍵字.NET4。將var repository = repositoryInfo.GetValue(this.db);'更改爲'dynamic repository = repositoryInfo.GetValue(this.db);' – qujck

回答

0

你想做的事情是行不通的,因爲爲了擁有一個強大的類型庫,你需要在編譯時知道實現你的接口的類型。但是你只知道它在運行時。

一個解決方案是引入一個非通用庫。

另一種解決方案是使用dynamic關鍵字。

dynamic repository = repositoryInfo.GetValue(this.db); 
repository.SomeMethod(...); 

但是,這意味着編譯器不再可以檢查涉及此動態變量的代碼。換句話說:如果SomeMethod不存在repository的實際類型a 運行時異常將被拋出而不是編譯器錯誤。

0

我會用一個基本的IRepository接口與你需要在這段代碼中進行交互的常用方法。

如果由於某種原因而無法實現,則可以採用鬆散耦合的方法,通過轉換爲動態或通過反射來獲取所需的方法。