首页 > 解决方案 > 在工厂中自动注册构造函数

问题描述

我有一个基类 DataSet 和几个派生类(DataSetSeries、DataSetTable、...)。派生类的构造函数每个都只接受一个参数,其类型特定于派生类,例如

public DataSetSeries(Series s);
public DataSetTable(Table t);

我编写了一个(通用)工厂类,它允许我从相应的原始数据类型创建 DataSet 子类的实例,例如

DataSet aDataSetSeries = DataSet.Factory.Create(aSeries);    
DataSet aDataSetTable = DataSet.Factory.Create(aTable);

其中 DataSet.Factory 是 DataSet 的静态只读字段。Create 所做的是确定其参数的类型,然后尝试从字典中查找相应的构造函数委托(之前已注册)并执行委托(如果存在)。

所以我必须在工厂注册每个派生类的构造函数。为了将相似的东西放在一起并且不要忘记为任何新的 DataSet 子类添加注册,我想在派生的 DataSet 类而不是 DataSet 本身中进行注册(它不应该知道它的任何派生严格的面向对象意义上的类)。因为 Factory 是静态的,所以我试图在每个派生的 DataSet 中包含一个静态构造函数,例如

public class DataSetSeries: DataSet
{
    static DataSetSeries()
    {
        Factory.Register(typeof(Series), data => new DataSetSeries((Series)data));
    }
    // ...
}

但现在这是我的问题:DataSetSeries 的静态构造函数只会在第一次使用 DataSetSeries 时被调用。但是我要做的第一件事是调用 DataSet.Factory.Create(aSeries),它不是 DataSetSeries 的方法,所以根本没有第一次使用 DataSetSeries。因此永远不会调用静态构造函数

如果不明确地迭代所有派生类型(这就是首先设置工厂的原因),我怎么能让它工作呢?

标签: c#factory

解决方案


您可以为工厂创建一个静态构造函数,并且在此构造函数中可以找到 Dataset 的所有子类(DataSetSeries、DataSetTable、...)。并为它们调用静态构造函数。

public static class Factory
{
    static Factory()
    {
        var datasetDerrivedTypes = Assembly
            .GetExecutingAssembly()
            .GetTypes()
            .Where(t => typeof(DataSet).IsAssignableFrom(t) &&
                        t != typeof(DataSet));

        foreach (var type in datasetDerrivedTypes)
        {
            System.Runtime.CompilerServices.RuntimeHelpers.RunClassConstructor(type.TypeHandle);  
        }
    }

    public static void Register(Type type, Func<Series, DataSet> constructorDelegate)
    {

    }
}

推荐阅读