如何错误检查此工厂创建使用带参数的激活器的<t>方法?</t>

时间:2012-02-09 22:31:08

标签: c# reflection factory

我不确定在此代码中调用激活器之前是否/如何检查构造函数是否实际存在(未经测试可能存在错误,但希望意图明确)。

好像我想要一个模板约束,上面写着“其中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;
        }
    }
}

3 个答案:

答案 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())

  

搜索参数匹配的公共实例构造函数   指定数组中的类型。