DDD:映射到具有大量数据库列的表的实体

时间:2015-02-16 15:11:00

标签: c# domain-driven-design entities

我正在尝试按照DDD方法构建实体,其中属性具有私有设置器和公共getter,并且通过构造函数完成赋值。这种方法的问题似乎是当你点击一个有很多列的表时,我们有一个至少有40列的表。它很快变成了一场噩梦。我发现一些文章似乎指向Fluent界面或工厂模式。看起来像40列,尽管清洁剂仍然可以失控,即使这些模式。列与表设计相关,不违反SRP。此外,在尝试维护表大小并且可能基于逻辑分组将实体分解为较小值的对象时,似乎某些值对象将变得很大。有人能指出我如何在不破坏DDD的情况下处理这种情况的正确方向吗?

1 个答案:

答案 0 :(得分:2)

这并不是说DDD不适合宽柱。 隐藏setter也不是DDD的特定要求,而是普通的旧封装。 (保护数据的修改。) 如果你必须设置很多这些值,并且发现自己混淆了代码,那么就像你提到的那样,将结构移到工厂。

当然,秘诀就是没有任何消费代码只是为你的域对象分配任何值而不遵循正确的"域逻辑",因此隐藏了setter。 当然有时您必须将所有这些值设置为您的域对象,并且值来自某些dto或mvc模型或其他东西,然后使用可以映射/分配值的Mapper类是保持消费代码清洁的好方法

你甚至可以考虑使用像Jimmy Bogard这样的AutoMapper:http://automapper.org/,顺便给私人制定者分配价值也没问题。

如果使用ORM加载数据,其中一些支持私有设置器和/或支持字段。 例如,NHibernate在您的映射文件中允许这样做:

this.Property(x => x.Description, mapper => mapper.Access(Accessor.Field))

根据我的评论,使用类似AutoMapper的东西来减轻大量映射代码的编写。 将实现包装在一个可注射的类中,如下所示,这样你可以在不执行鸟枪手术的情况下替换实现。

public class ViewMapper<TModel, TDomain> : IViewMapper<TModel, TDomain>
{
    public TDomain MapToDomain(TModel dataItem)
    {
        return Mapper.Map<TModel, TDomain>(dataItem);
    }

    public List<TDomain> MapToDomain(IEnumerable<TModel> dataItems)
    {
        return dataItems.Select(this.MapToDomain).ToList();
    }

    public TModel MapToData(TDomain domainItem)
    {
        return Mapper.Map<TDomain, TModel>(domainItem);
    }

    public void MapToOriginalData(TDomain domainItem, TModel dataItem)
    {
        Mapper.Map(domainItem, dataItem);
    }

    public List<TModel> MapToData(IEnumerable<TDomain> domainItems)
    {
        return domainItems.Select(this.MapToData).ToList();
    }
}

AutoMapper具有高度可配置性,应该能够处理大多数情况。 设置映射器配置文件,您可以在其中准确地告诉它在映射期间要做什么:

public class ViewItemProfile : AutoMapper.Profile
{
    protected override void Configure()
    {
        Mapper.CreateMap<Domain, View>()
            .ForMember(x => x.ErrorRequestId, y => y.MapFrom(z => z.ErrorTypeId))
            .ForMember(x => x.Irrelevant, y => y.Ignore());
    }
}