2012-01-03 98 views
2

我有一個泛型類是這樣的:如何強制泛型類使用T構造函數的參數?

public class Mapper<TEntity, TDataAccess> 
    where TEntity : Common.IEntity 
    where TDataAccess : DataAccess, new() 
{ 
    public TDataAccess DataAccess { get; set; } 
    public Mapper() 
    { 
     DataAccess = new TDataAccess(); 
    } 
    /* 
    * ... 
    * */ 
} 

和數據訪問是這樣的:

public class DataAccess 
{ 
    public DataAccess() 
    {} 

    public DataAccess(string tranName) 
    {} 

    // CRUD functionality and other data access staff 
} 

和繼承類的形式DataAccess

public class UserDataAccess:DataAccess 
{ 
    public UserDataAccess():base(string.Empty) 
    { 
    } 
    public UserDataAccess(string tranName):base(tranName) 
    { 
     // Something to do with user 
    } 
} 

終於從映射UserMapper

public class UserMapper : Mapper<User,UserDataAccess> 
{ 
    // Mapping entity properties with datarows columns 
} 

現在想象一下,我需要發送tranName給定TDataAccessUserMapper。如何在不改變DataAccess類的情況下做到這一點?我無法訪問DataAccess的源代碼,並且泛型沒有實現類型不同的構造函數重載。 我知道我可以在UserDataAccess上擁有一個屬性並在需要時填充它,但由於線程安全問題,我無法填充該屬性。

User類是一個普通的實體 - 它只有屬性。

回答

2

泛型不支持。選項:

  • protected virtual TDataAccess CreateDataAccess()方法,即默認使用new TDataAccess(),但可以通過UserMapper覆蓋創建對象時,它喜歡的任何方式;調用CreateDataAccess()代替new TDataAccess()
  • 通在工廠方法作爲代表,即Func<TDataAccess> - 這樣的呼叫者可以提供() => new DataAccess("foo"),和使用,代替new TDataAccess()
  • 使用基於反射的代碼來創建TDataAccess - 要麼Activator.CreateInstance (支持參數),或一些涉及元編程(ExpressionILGenerator等)
+0

Activator.CreateInstance工程師。謝謝;) – MDP 2012-01-03 10:07:31

3

如可以通過指定構造參數使用Activator.CreateInstance()方法的過載的情況下:

var dataAccess = Activator.CreateInstance(
          typeof(TDataAccess), 
          new object[] { tranName }); 

MSDN

public static Object CreateInstance(
    Type type, 
    params Object[] args 
) 

使用 最好與指定參數匹配的構造創建指定類型的一個實例。

+0

謝謝sll,這是grate idea;) – MDP 2012-01-03 10:08:23

+0

很高興聽到,不客氣 – sll 2012-01-03 16:34:54

相關問題