ASP.NET MVC / DDD架构有帮助

时间:2009-05-09 15:42:17

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

我正在使用ASP.NET MVC创建一个Web应用程序,我正在尝试使用域驱动设计。我有一个架构问题。

我有一个WebControl表来存储列表的键和值,因此它们可以编辑。我已将其合并到我的商业模式中,但它导致了大量冗余代码,我不确定它是否属于那里。例如,在我的Request类中,我有一个名为NeedType的属性。因为这来自列表,我创建了一个NeedType类来提供单选按钮的值。我在这里只展示了一个例子,但表单中可能有十几个需要来自数据库的列表。

[编辑,澄清问题]有什么更好的方法呢?这些列表对象是否真的是我的域的一部分,还是仅存在于UI中?如果不是域的一部分,那么它们不属于我的Core项目,那么它们去哪里了?

public class Request : DomainObject
{
   public virtual int RequestId { get; set; }
   public virtual DateTime SubmissionDate { get; set; }
   public virtual string NeedType { get; set; }
   public virtual string NeedDescription { get; set; }
   // etc.
}

public class NeedType : DomainObject
{
    public virtual int NeedTypeId { get; set; }
    public virtual string NeedTypeCode { get; set; }
    public virtual string NeedTypeName { get; set; }
    public virtual int DisplayOrder { get; set; }
    public virtual bool Active { get; set; }
}

public class RequestController : Controller
{
    private readonly IRequestRepository repository;

    public RequestController()
    {
        repository = new RequestRepository(new HybridSessionBuilder());
    }

    public RequestController(IRequestRepository repository)
    {
        this.repository = repository;
    }

    public ViewResult Index(RequestForm form)
    {
        ViewData.Add("NeedTypes", GetNeedTypes());
        if (form == null)
        {
            form = new RequestForm();
            form.BindTo(repository.GetById(125));
        }
    }

    private NeedType[] GetNeedTypes()
    {
        INeedTypeRepository repo = new NeedTypeRepository(new HybridSessionBuilder());
        return repo.GetAll();
    }
}

3 个答案:

答案 0 :(得分:3)

使用视图中所需的数据创建单独的viewmodel。 MVC的M中的模型与域模型不同。 MVC视图模型是愚蠢的DTO,没有行为,只有属性。域模型具有尽可能多的行为。带get; set;的域模型;仅属性被认为是称为“贫血域模型”的反模式。大多数人放置视图模型有两个地方:在Web层中,靠近视图和控制器,或在应用程序服务层中。

编辑:

当您只需要在数据库中显示所有需要类型的列表和视图中的一个请求时,我确实会创建一个包含请求和需求类型列表作为属性的viewmodel。我不认为在控制器中调用多个存储库是一种气味,除非你有一个更大的应用程序,并且你可能想要一个单独的应用程序服务层,它通过一个方法调用返回整个viewmodel。

我认为遵循托德史密斯关于价值对象的建议也许是一个好主意。 当用户在运行时添加或编辑needtypes时,needtype应该是一个实体。当needtypes被硬编码并且仅在项目的新版本中更改时,needtype应该是值对象,并且needtypes列表可以通过NeedType.GetAll()填充并通过向请求表添加列来存储在数据库中而不是一个单独的needtype表。

答案 1 :(得分:1)

如果它来自列表,那么我打赌这是一个外键。在设计域模型时,根本不要考虑您的UI。这只是NeedType是外键的情况。将字符串NeedType替换为对实际NeedType对象的引用。在您的数据库中,这将是对id的引用。

当您构建NeedType选项列表时,您只需要提取每个NeedType。如果它没有太大变化,也许保持缓存是一个好主意。

答案 2 :(得分:1)

你的NeedType对我来说看起来像一个值对象。如果它是只读数据,则应将其视为DDD体系结构中的值对象,并且属于您的域。

由于您不再使用旧数据库,很多人在处理DDD时会遇到“omg so much redundancy”问题 - > DataTable - > UI方法。