【问题标题】:Is it bad practice to have a class helper to convert DAL objects to Core objects有一个类助手将 DAL 对象转换为核心对象是不好的做法吗
【发布时间】:2014-06-13 20:40:12
【问题描述】:

我正在努力为我当前的项目找到一个好的架构。这是我第一次尝试使用软件工程的最佳实践(DI、单元测试等)来设计一个严肃的 n 层应用程序。我的项目使用的是 Onion 架构。

我有 4 层

  1. 核心层:它保存着我的业务对象。在这里,我有代表我的业务实体的类及其方法。其中一些对象引用了服务接口。

  2. DAL(数据访问)层:它定义 POCO 对象并实现核心层中定义的存储库接口。在这一层中,我认为设计一个大型实用程序类是个好主意,其作用是将 POCO 对象从 DAL 转换为来自核心的业务对象。

  3. 服务层:它实现了核心中定义的服务接口。该层的作用是提供对 DAL 中定义的存储库的访问。我主要认为这个层没有用,所以我直接使用了核心层中定义的存储库接口。然而,在花了几个星期编写很长的实例化代码之后——让构造函数采用 5-6 个 IRepository 参数——我明白了服务层的意义。

  4. 表示层。这里没什么特别要说的,只是我在这个Layer中配置了依赖注入(我用的是Ninject)。

我已经更改了架构并至少重写了 3 次代码,因为很多时候我发现我的代码有问题。 (例如带有长参数列表的长构造函数)。幸运的是,我对文献中发现的各种编码模式有所了解。

但是我刚刚遇到了我的 DI 的周期性依赖,我很想知道我的 DAL2Core Helper 是否是个好主意...

感谢这个助手,我可以编写如下代码:

        DAL.Point p = DAL2Core.PointConverter(point); // point is a Core Object
        context.Points.Add(p);
        context.SaveChanges();

这减少了一点代码冗余。然后我在 DAL 中定义的每个存储库都有自己的 DAL2Core 成员:

private IDAL2CoreHelper DAL2Core;

我从 Repository 构造函数注入它。

DAL2Core 类本身有点乱... 首先,它对每个存储库和每个处理器(服务层)都有一个属性。处理器存在的原因是我的核心对象需要注入处理器依赖项。我将我的 DAL2Core 实用程序类中引用的一些存储库和处理器放在下面只是为了说明:

    [Inject]
    private Core.IUserRepository UserRepository{ get; set; }
    [Inject]
    private Core.IPointsRepository PointsRepository { get; set; }


...

    [Inject]
    private Core.IUserProcessor UserProcessor{ get; set; }
    [Inject]
    private Core.IPointsProcessor CoursProcessor { get; set; }

(由于存储库需要 DAL2Core Helper,因此构造函数注入会导致循环依赖)

然后这个类有很多简单的方法,例如:

public Core.User UserConverter(DAL.User u)
    {
        Core.User user = new Core.User(UserProcessor);   
        user.FirstName= u.FirstName;
        user.Name= u.Name;
        user.ID = u.ID;
        user.Phone= u.Phone;
        user.Email= u.Email;
        user.Birthday= u.Birthday;
        user.Photo = u.Photo;
        return user;
    }

这个类是 60000 行。想一想,我意识到我并没有节省太多代码,因为很多时候 DAL2Core 转换代码只从一个地方调用,所以也许最好将此代码留在存储库中?而且 - 最大的问题 - 因为我决定将此帮助程序与我的存储库类分离,所以 Ninject 会抛出周期性依赖异常。

您如何看待我尝试的设计,这是一种好的/常见的做法吗?以及如何巧妙而有效地执行此 DAL2Core 转换而不会产生代码异味。我真的很期待解决这个架构问题,过去三周我一直在处理管道和架构问题,并没有真正推进那个项目。我变得很晚了。但是我真的很想制作高质量的代码。我只是想避免对我来说看起来有点矫枉过正的架构解决方案,有很多工厂等......但我承认有时,这种感觉只是来自我缺乏理解(比如服务层)。

提前感谢您的帮助!

【问题讨论】:

    标签: c# asp.net-mvc n-tier-architecture onion-architecture


    【解决方案1】:

    您希望使用的是 AutoMapper 、值注入器或类似的东西。

    本质上,在层之间分离数据模型是一种很好的做法,可以减少耦合并提高可测试性。如果您想出一个通用的 Mapper,您将减少代码冗余。

    希望这会有所帮助。

    【讨论】:

    • +1 AutoMapper 也是我的建议。
    • 还有一点是,使用 AutoMapper 或类似的东西,将强制映射到其自身的图层/方面。这可能有助于测试。在生产中,我们使用了构建器(例如您的助手,但实例不是静态的以帮助模拟)和 AutoMapper 的组合,我们可以在对象到对象的映射上提供断言以增加信心。
    • 谢谢,看来这正是我所需要的!我希望我不必重命名很多属性。但无论如何,这似乎是要走的路。
    • 嗯,我刚刚阅读了很多文档,我发现并不是每个人都同意在 DAL 中使用 Automapper 是否是一个好主意。我想避免一些缺点。 devtrends.co.uk/blog/…rogeralsing.com/2013/12/01/…
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-18
    • 1970-01-01
    相关资源
    最近更新 更多