我不确定在此代码中调用激活器之前是否/如何检查构造函数是否实际存在(未经测试可能存在错误,但希望意图明确)。
好像我想要一个模板约束,上面写着“其中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 :(得分:3)
不,你不能 - 唯一可用的构造函数相关通用约束是new()
,它需要一个无参数的构造函数。
一种选择是要求工厂代表:
public T Create<T>(Func<EntityConnection, T> factory)
{
return factory(CreateEntityConnection());
}
然后你可以使用:
Create(connection => new Whatever(connection))
或其他任何可构建适当对象的内容。它更灵活,更安全,性能也更好。 (后者可能无关紧要,诚然......)
答案 1 :(得分: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);
}
答案 2 :(得分:1)
Type.GetConstructor Method (Type())
搜索参数匹配的公共实例构造函数 指定数组中的类型。