2012-02-09 64 views
0

我不确定在代码中调用激活器之前是否/如何检查构造函数实际存在(未经测试,因此可能有错误但希望其意图清晰)。如何错误检查此工厂创建<T>使用参数激活器的方法?

它就好像我想要一个模板约束,它说“哪里T有一个带签名S的构造函数”。

public class EntityContainerFactory 
{ 
    public EntityContainerFactory(string sqlServerName, string databaseName, string metaData) 
     : this(sqlServerName, databaseName, metaData, "System.Data.EntityClient") 
    { 
    } 

    public EntityContainerFactory(string sqlServerName, string databaseName, string metaData, string dataProviderName) 
    { 
     SqlServerName = sqlServerName; 
     DatabaseName = databaseName; 
     Metadata = metaData; 
     DataProviderName = dataProviderName; 
    } 

    // --> IS THERE ANY WAY TO CHECK THAT T HAS 
    //  A CONSTRUCTOR THAT TAKES AN ENTITY CONNECTION? 
    public T Create<T>() 
    { 
     return (T)Activator.CreateInstance(typeof(T), CreateEntityConnection()); 
    } 

    EntityConnection CreateEntityConnection() 
    { 
     SqlConnectionStringBuilder sqlBuilder = new SqlConnectionStringBuilder(); 
     sqlBuilder.DataSource = SqlServerName; 
     sqlBuilder.InitialCatalog = DatabaseName; 
     sqlBuilder.IntegratedSecurity = true; 

     EntityConnectionStringBuilder entityBuilder = new EntityConnectionStringBuilder(); 
     entityBuilder.Provider = DataProviderName; 
     entityBuilder.ProviderConnectionString = sqlBuilder.ToString(); 
     entityBuilder.Metadata = Metadata; 

     return new EntityConnection(entityBuilder.ConnectionString); 
    } 

    public string DatabaseName { get; set; } 

    public string SqlServerName { get; set; } 

    public string DataProviderName { get; set; } 

    private string metaData; 
    public string Metadata 
    { 
     get 
     { 
      string result; 
      if (!this.metaData.StartsWith("res://")) 
      { 
       result = string.Format(@"res://*/{0}.csdl|res://*/{0}.ssdl|res://*/{0}.msl", this.metaData); 
      } 
      else 
      { 
       result = this.metaData; 
      } 
      return result; 
     } 
     set 
     { 
      this.metaData = value; 
     } 
    } 
} 
+0

请花时间粘贴相关代码,而不是整块或全班。 – 2012-02-09 22:36:27

回答

3

您是否考虑过使用接口而不是工厂?你可以得到更好的结果,而且你不会遇到这样的问题。

总之:

where T : new() 

仅适用于参数构造函数。当你有这个约束,你可以做到以下,没有反射:

T obj = new T(); 

你将不得不手动检查。

ConstructorInfo ctor = typeof(T).GetConstructor(new Type[] { EntityConnection }); 
if (ctor == null) 
{ 
    // Handle an unwanted type. 
} 
else 
{ 
    return (T)ctor.Invoke(entityConnection); 
} 
3

不,你不能 - 唯一可用的构造函数相关的通用的限制是new()这需要一个参数的构造函数。

一种选择是要求厂家代表来代替:

public T Create<T>(Func<EntityConnection, T> factory) 
{ 
    return factory(CreateEntityConnection()); 
} 

然后你可以使用:

Create(connection => new Whatever(connection)) 

或其他任何东西,将建立适当的对象。它更灵活,更安全,性能也更好。 (后者可能无关紧要,无可否认......)

相关问题