命令处理程序模式中嵌套的DTO?

时间:2014-04-18 09:16:46

标签: c# dto datacontract command-pattern

我正在为我正在设计的服务实现Command-Handler模​​式,其中Command本质上是Handler的.Handle()方法的DTO。到目前为止,这一切都是相当直接的,但我遇到了一个实施问题,让我了解它的气味。

我是否应该使用相应的CommandHandler所需的额外特定数据来创建扩展ICommand的接口...或者我应该在ICommand接口上创建.Data属性来访问嵌套的Dto对象吗?

选项#1

public interface ICommand
{
    Guid Id { get; set; }
    string Name { get; set; }
    CommandStatus Status { get; set; }
    TimeSpan Elapsed { get; set; }
}

[KnownType(typeof (DeleteProjectLogCommand))]
[DataContract(Name = "Command")]
public abstract class CommandBase : ICommand
{
    [DataMember]
    public Guid Id { get; set; }
    [DataMember]
    public string Name { get; set; }
    [DataMember]
    public CommandStatus Status { get; set; }
    [DataMember]
    public TimeSpan Elapsed { get; set; }
}

public interface IDeleteProjectCommand : ICommand
{
    long? ProjectId { get; set; }
}

[DataContract(Name = "DeleteProjectLogCommand")]
public class DeleteProjectLogCommand : CommandBase, IDeleteProjectCommand
{
    [DataMember]
    public long? ProjectId { get; set; }
}

选项#2

public interface ICommand
{
    Guid Id { get; set; }
    string Name { get; set; }
    CommandStatus Status { get; set; }
    TimeSpan Elapsed { get; set; }
    DataDto Data { get; set; }
}

[KnownType(typeof(ProjectDto))]
[DataContract(Name = "DataDto")]
public abstract class DataDto
{
    [DataMember]
    long? Id { get; set; }
    bool IsNew { get; set; }
}

public class ProjectDto : DataDto
{
    public long? OrganizationId { get; set;}
    public ProjectType ProjectType { get; set;}
    // ...etc
}

[DataContract(Name = "DeleteProjectLogCommand")]
public class DeleteProjectLogCommand : CommandBase
{
    // ...in this instance no other data is needed, 
    // making this basically just an empty Decorator of CommandBase
}

第二个例子是一个小DRY'er,但它的代价是有一个更胖的DataContracts和一些现在空的抽象CommandBase装饰,否则将从更简洁的接口实现。

1 个答案:

答案 0 :(得分:0)

我认为第二种选择失去了专门命令的本质。您也可以将DeleteProjectLogCommand重命名为CRUDCommand。此外,通过在DataDto中引入通用ICommand有效负载,您可以限制实现的功能,顺便说一下,在许多情况下可能不需要。而你的ProjectDto正在处理你的命令属性。

我坚持你的第一个选择。更重要的是,我可能会摆脱IDeleteProjectCommand以保持简单。