【问题标题】:Is mapping a part of Data or Logic/Business layer?映射是数据层还是逻辑/业务层的一部分?
【发布时间】:2018-11-01 18:00:21
【问题描述】:

我正在开发 N 层服务应用程序,基本上是(我有一个非常具体的问题,但我需要先解释一下整个情况/架构)

数据 --> 逻辑(业务)--> WCF 服务 --> 主机(Winddows 服务),其中:

Data,是数据持久化,但它没有连接字符串。一切都取自另一个 WCF 服务。所以我这里只有ServiceReferences 和一个类FooData,还有一些方法(它实现了IFooData 接口)。正如您在下面看到的,它返回Bar 对象,该对象来自BarServiceReference 由VS 自动生成。

using FooService.Data.BarServiceReference;

public class FooData : IFooData
{
    public BarDto Func1(int id)
    {
        try
        {
            using (BarServiceClient client = new BarServiceClient())
            {
                return client.GetBar(id);
            }
        }
        catch (System.ServiceModel.FaultException ex)
        {
            throw new Exception($"Inner exception in BarServiceClient: { ex.Message }", ex);
        }
    }        
}

逻辑,这里有IMapper 的映射配置文件和FooLogic 类,我通过DI 注入IFooDataIMapper。在那个类里面我有一些方法。其中之一:

public class FooLogic
{
    private IMapper Mapper { get; }
    private IFooData FooData { get; }
    public FooLogic(IMapper mapper, IFooData fooData)
    {
        Mapper = mapper;
        FooData = fooData;
    }

    public Bar GetBar(int id)
    {
        BarDto barDto = FooData.Func1(itemId);
        Bar bar = Mapper.Map<BarDto, Bar>(barDto);  

        // There are lot more, taken from the Data layer.
        // Some operations are performed.  The Bar is basically modified a little bit/adjusted



        return bar;
    }
}  

如您所见,我的逻辑层必须知道“BarDto”,这迫使我使用引用。我不确定。

问题...

我应该从Data 层返回Bar 而不是BarDto?在这种情况下,我将不得不将 IMapper 注入数据层。我读过很多书,有些人在数据层做,有些人在逻辑层做。像你的映射应该在逻辑层而不是数据层这样的引用,所以我很困惑。

感谢您的帮助

【问题讨论】:

  • 数据层应该通过实现数据访问接口依赖于逻辑层。通过在业务层进行映射,您会将数据层的实现细节泄漏到业务层,这将破坏分层的主要目的。
  • @Fabio 谢谢,只是为了确保,您是说映射应该在数据端完成(传入数据到逻辑实体),对吗?我正在编写单元测试,我发现自己在编写 IFooData 模拟时引用了数据层。所以(如果我错了,请纠正我),IFooData 接口应该返回逻辑实体,对吧?
  • 是的,业务层会创建与业务实体的数据访问接口。数据访问层将实现这些接口,因此如果数据访问层使用自己的实体类型,它将负责将它们映射回业务类型
  • @Fabio 那么我应该把IFooData 接口放在哪里呢?如果我将它留在Data 项目中,那么Logic 将不得不引用Data 项目。对吗?
  • IFooData 接口应该在业务/逻辑层。但它的实现将在数据层中

标签: c# .net wcf architecture n-tier-architecture


【解决方案1】:

我将把您的另一个 WCF 服务称为 数据源服务,它有自己的数据合同,它通过其操作返回到您的数据访问层。现在您的服务层应该不知道您的数据源服务对象的任何信息。它应该与它们无关,因此将来,如果您计划使用另一个数据源而不是另一个 WCF 服务,则不必担心重新编译您的服务层。您的服务层不应该对数据源有任何引用,这是使用单独的数据访问层背后的想法之一。

因此,要回答您的问题,请在自己的数据层而不是服务层中进行映射。

【讨论】:

  • 你的服务层不应该有任何对数据源的引用 - Logic 项目怎么会知道要调用哪些数据函数? IFooData 应该在哪里实现?我是否应该只使用接口创建单独的 Core 项目?
  • 是的,所有常见接口和类的单独项目。 IFooData 应该在 Data 项目中实现。 Logic 项目仅包含对 Common 项目的引用,并使用依赖注入在运行时加载实现。您可以使用任何 DI 容器在主项目中注册所有依赖项。
猜你喜欢
  • 1970-01-01
  • 2010-12-22
  • 2014-09-04
  • 1970-01-01
  • 2011-10-23
  • 2010-12-18
  • 1970-01-01
  • 1970-01-01
  • 2016-08-12
相关资源
最近更新 更多