【问题标题】:ASP.NET MVC - Polymorphic domain classes and view modelsASP.NET MVC - 多态域类和视图模型
【发布时间】:2012-12-07 17:55:22
【问题描述】:

让我们考虑一个订单历史的域抽象类和考虑付款、取​​消、重新激活等事件的具体类(以下代码是一个非常简化的版本)

public abstract class OrderEvent
{
    protected OrderEvent(DateTime eventDate)
    {
        EventDate = eventDate;
    }

    public abstract string Description { get; }
    public DateTime EventDate { get; protected set; }
}

public class CancellationEvent : OrderEvent
{
    public CancellationEvent(DateTime cancelDate)
        : base(cancelDate)
    {

    }
    public override string Description { get { return "Cancellation"; } }
}

public class PaymentEvent : OrderEvent 
{
    public PaymentEvent(DateTime eventDate, decimal amount, PaymentOption paymentOption) : base(eventDate)
    {
        Description = description;
        Amount = amount;
        PaymentOption = paymentOption;
    }

    public override string Description { get{ return "Payment"; } }
    public decimal Amount { get; protected set; }
    public PaymentOption PaymentOption { get; protected set; }
}

现在我必须在这个域模型上为我的 ASP.NET MVC 项目构建一个 ViewModel,它将所有事件封装到一个类中,以便在视图上进行网格展示。

public class OrderHistoryViewModel
{
    public OrderHistoryViewModel(OrderEvent orderEvent)
    {
        // Here's my doubt

    }

    public string Date { get; protected set; }
    public string Description { get; protected set; }
    public string Amount { get; protected set; }
}

我怎样才能访问具体类中的特定属性,例如 PaymentEvent 上的 Amount 属性,而不需要做一些像 switch 或 if 这样的臭名昭著的事情?

谢谢!

【问题讨论】:

    标签: asp.net-mvc oop domain-driven-design polymorphism


    【解决方案1】:

    如果您使用的是 .NET 4 及更高版本,请执行 double dispatch

    public class OrderHistoryViewModel
    {
        public OrderHistoryViewModel(OrderEvent orderEvent)
        {
           // this will resolve to appropriate method dynamically
           (this as dynamic).PopulateFrom((dynamic)orderEvent);
        }
    
        void PopulateFrom(CancellationEvent e)
        {
        }
    
        void PopulateFrom(PaymentEvent e)
        {
        }
    
        public string Date { get; protected set; }
        public string Description { get; protected set; }
        public string Amount { get; protected set; }
    }
    

    就我个人而言,我并不介意在这种类型的代码中使用 if/switch 语句。这是应用程序边界代码,不需要非常漂亮,并且明确会有所帮助。 C# 真正需要的是algebraic types,例如union type in F#。这样,编译器将确保您显式处理所有情况(子类型)。

    【讨论】:

    • 不断收到错误,指出 TYPE 的最佳重载方法有一些无效参数。 :-\
    猜你喜欢
    • 1970-01-01
    • 2011-10-24
    • 1970-01-01
    • 2010-12-06
    • 1970-01-01
    • 2011-01-01
    • 1970-01-01
    • 2023-03-06
    • 1970-01-01
    相关资源
    最近更新 更多