我正在构建一个修复了数据模型的应用程序,但是人们(或者只是我)可以通过添加继承自基类的类来扩展它,这些类从db中的信息实例化并在服务中序列化。
我有三个问题区域(下面的示例代码中的案例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; }
}
}
答案 0 :(得分:2)
听起来你正在尝试构建一个微型可扩展性框架。考虑这样的事情,其中扩展逻辑由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 = ...;
}
答案 1 :(得分:2)
对于可扩展的字段阅读:
使字段成为一个抽象类,并使所有常用方法都抽象化。从Field派生的类将精确指定这些方法的作用。
然后,您可以将这些派生类的对象传递回接受Field的方法,并且可以调用Field的方法,而无需担心正在使用的实际类。接口会更好,但是你没有为常用功能重用代码。
对于可扩展的字段创建:
您将始终必须在程序的边界处进行切换或某事以确定要创建的类。您的目标是仅在一个地方执行此操作。您的设计 - 根据数据库中的数据确定使用的工厂方法 - 是理想的选择。
研究制作一个有责任根据数据库数据创建Field对象的类,然后传递它。如果它是抽象的,你可以将它子类化并将其作为参数传递给方法,这些方法将通过调用类似fieldFactory.GetNewField(myParameter);来获取所需的数据。
对于可扩展序列化:
Research DataContractResolver。
提示:
如果你发现自己必须在多个地方(调用构造函数的地方)中打开Field的类型,那么你做错了。这方面的一个例子是您的进程(字段)方法。相反,Field或IField应该有一个抽象的Process方法。消费者只需调用Field.Process,而不关心它是如何实现的。
示例:
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(); }
}