为一些字段值和其他扩展点添加处理程序

本文关键字:扩展 添加 处理 程序 其他 字段 | 更新日期: 2023-09-27 18:01:42

我正在构建一个数据模型固定的应用程序,但是人们(或者只是我)可以通过添加继承基类的类来扩展它,基类从数据库中的信息实例化并在服务中序列化。

我有三个问题区域(下面示例代码中的案例1、2和3)。情况1我可以用界面来解决,但这对情况2或3没有帮助。

我认为代码示例会比我试图解释的更好;任何想法如何处理这一点,使每个新的字段类型不需要手动添加到代码中的一堆地方?

    public class ManagerClass
{
    public ManagerClass()
    {
        public ManagerClass()
        {
        }
        //Case #1
        public void process(AllFields allFields)
        {
            foreach (Field field in allFields.Fields)
            {
                //Currently I need to add all extention types as seperate cases here manually
                //...this type of logic appears in several places in the code
                if (field.GetType().Name == "ExtendedField")
                {
                    //Have the extended field do something in a way particular to it
                }
                else
                {
                    //Have the base field do something the "normal" way
                }
            }
        }
        //Case #2
        //Here is another case where currently I am adding each case in by hand
        //fieldType is a string here because I am storing what type of field it is in the DB
        public void create(string value, string fieldType)
        {
            //Currently I need to add all extention types as seperate cases here manually
            if (fieldType == "ExtendedField")
            {
                //Create a ExtendedField
            }
            else
            {
                //Create a Field
            }
        }
    }
}
[DataContract]
//Case #3
[KnownType(typeof(ExtendedField))] //Currently I need to add all extention types here manually
public class AllFields
{
    private List<Field> fields;
    public AllFields(){}
    [DataMember]
    public List<Field> Fields
    {
        get { return fields; }
        set { fields = value; }
    }
}
[DataContract]
public class Field
{
    private string fieldValue;
    public Field(){}
    [DataMember]
    public string FieldValue
    {
        get { return fieldValue; }
        set { fieldValue = value; }
    }
}
[DataContract]
public class ExtendedField : Field
{
    private string someOtherAttribute;
    public ExtendedField(){}
    [DataMember]
    public string SomeOtherAttribute
    {
        get { return someOtherAttribute; }
        set { someOtherAttribute = value; }
    }
}

为一些字段值和其他扩展点添加处理程序

听起来您正在尝试构建一个微型可扩展性框架。考虑这样的情况,其中扩展逻辑由FieldHandler处理:

public class FieldHandler
{
   public virtual Field CreateField(string value, string fieldType){...}
}
// Case 2
Field field = null;
foreach (FieldHandler handler in m_handlers)
{
   if (handler.SupportsFieldType(fieldType))
   {
       field = handler.CreateField (value, fieldType);
       continue;
   }
}
if (field == null)
{
   // Create standard field.
   field = ...;
}

可扩展字段读取:

使Field成为一个抽象类,并使所有的常用方法都是抽象的。从Field派生的类将确切地指定这些方法的功能。

您可以将这些派生类的对象传递给接受Field的方法,并且它们可以调用Field的方法,而无需担心正在使用的实际类。接口会更好,但是你没有得到代码重用的通用功能。

用于创建可扩展字段:

你总是需要在程序边界的某个地方做一个开关或其他事情来决定要创建哪个类。你的目标是只在一个地方做这件事。您的设计——根据数据库中的数据确定要使用的工厂方法——是理想的。

考虑制作一个类,它将有责任创建基于DB数据的Field对象,并只是传递它。如果它是抽象的,你可以子类化它,并将它作为参数传递给方法,方法将通过调用fieldFactory.GetNewField(myParameter);来获得他们想要的数据。

可扩展序列化:

研究DataContractResolver。

提示:

如果您发现自己必须在多个地方(调用构造函数的地方)打开Field的类型,那么您就做错了。流程(字段)方法就是一个例子。相反,Field或IField应该有一个抽象的Process方法。消费者只会打电话给Field。过程而不关心如何实现。

的例子:

public abstract class Field
{
   public abstract void Process();
}
public class ExtendedField : Field
{
   public override void Process() { /*Extended Field Specific Stuff Here*/ }
}
//consumer code
public void DoStuffWithABunchOfFieldsOfUnknownType(IEnumerable<Field> fields)
{
   foreach (Field field in fields) { field.Process(); }
}