在DTO中有可选参数可以吗?

时间:2013-09-06 11:23:53

标签: c# design-patterns dto

我在这里有点困惑。我有一个场景,根据所选的选项,我的DTO的某些属性才有效。所以,我提出了以下设计。

[DataContract]
class MyDTO
{
    [DataMember]
    public BaseData CommonData { get; set; }
    [DataMember]
    public Options AvailableOptions { get; set; }
    [DataMember]
    public Option1Data Data1 { get; set; }
    [DataMember]
    public Option2Data Data2 { get; set; }
}
[DataContract]
public class BaseData
{
    [DataMember]
    public int BaseVar1 { get; set; }        
}

[DataContract]
public enum Options
{
    [EnumMember]
    Option1,
    [EnumMember]
    Option2
}

[DataContract]
public class Option1Data
{
    [DataMember]
    public string Option1Var1 { get; set; }
}

[DataContract]
public class Option2Data
{
    [DataMember]
    public string Option2Var1 { get; set; }
}

但显然MyDTO类违反了OCP原则。在Options枚举中添加了一个新选项时,我需要更改MyDTO以添加一个属性来检索该选项的数据。

在这种情况下可以更改MyDTO还是你有更好的设计?

1 个答案:

答案 0 :(得分:0)

继承怎么样?

[DataContract]
[KnownType(typeof(Option1))]
[KnownType(typeof(Option2))]
public abstract class BaseData
{
    [DataMember]
    public int BaseVar1 { get; set; }        
}

[DataContract]
public class Option1 : BaseData
{
    [DataMember]
    public string Option1Var1 { get; set; }
}

[DataContract]
public class Option2 : BaseData
{
    [DataMember]
    public string Option2Var1 { get; set; }
}

您还可以添加enum以方便switch等使用,但它不需要是[DataMember],因为它实际上是多余的信息:

public enum Options
{
    Option1,
    Option2
}

[DataContract]
[KnownType(typeof(Option1))]
[KnownType(typeof(Option2))]
public abstract class BaseData
{
    [DataMember]
    public int BaseVar1 { get; set; }        
    [IgnoreDataMember]
    public abstract Options Option {get;}
}

[DataContract]
public class Option1 : BaseData
{
    [DataMember]
    public string Option1Var1 { get; set; }
    [IgnoreDataMember]
    public override Options Option {get { return Options.Option1; } }
}

[DataContract]
public class Option2 : BaseData
{
    [DataMember]
    public string Option2Var1 { get; set; }
    [IgnoreDataMember]
    public override Options Option {get { return Options.Option2; } }
}