使用类助手将DAL对象转换为Core对象是不好的做法

时间:2014-04-28 10:32:17

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

我正努力为我当前的项目获得一个好的架构。我第一次设计一个严肃的n层应用程序,试图使用软件工程的最佳实践(DI,单元测试等......)。我的项目正在使用Onion架构。

我有4层

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

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

  3. 服务层:它实现了Core中定义的服务接口。此层的作用是提供对DAL中定义的存储库的访问。我首先认为这层没用,所以我直接使用了我的核心层中的Repository Interfaces定义。然而,经过几周的编写非常长的实例代码 - 让构造函数采用5-6个IRepository参数 - 我得到了服务层的意义。

  4. 演示层。这里没什么特别的,除了我在这个层中配置依赖注入(我使用Ninject)。

  5. 我已经改变了我的架构,并且至少重写了我的代码3次,因为很多时候我看到我的代码出了问题。 (像长参数列表的长构造函数)。幸运的是,每比特一点,我得到了在文学中发现的各种编码模式的观点。

    然而,我只是遇到了与我的DI的周期性依赖,我真的很想知道我的DAL2Core助手是不是一个好主意...

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

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

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

    private IDAL2CoreHelper DAL2Core;
    

    我从Repository构造函数中注入它。

    DAL2Core类本身有点凌乱...... 首先,它为每个存储库和每个处理器(服务层)都有一个属性。存在处理器的原因是我的Core Objects需要注入处理器依赖。我在下面的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;
        }
    

    这个类就像600行。考虑到这一点,我意识到我不会节省太多代码,因为大多数情况下DAL2Core转换代码只从一个地方调用,所以将这些代码留在存储库中也许会更好?而且 - 最大的问题 - 因为我决定将这个帮助器与我的Repository Classes分离,所以Ninject抛出了循环依赖异常。

    您对我尝试过的设计有何看法,这是一种好的/通常的做法吗?如何在没有代码味道的情况下巧妙而高效地执行此DAL2Core转换。我真的很期待解决这个架构问题,过去三周我一直在处理管道和架构问题而不是真正推进该项目。我变得很晚了。但是我真的想要生成高质量的代码。我只是想避免对我来说看起来像过度杀伤的建筑解决方案,有很多工厂等......但我承认,有时候,这种感觉来自我缺乏理解(比如服务层)。

    提前感谢您的帮助!

1 个答案:

答案 0 :(得分:3)

您要使用的是AutoMapper,Value injecter或类似用途。

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

希望这有帮助。