【问题标题】:How do i avoid referencing DataLayer in UI layer?如何避免在 UI 层中引用 DataLayer?
【发布时间】:2011-05-27 22:24:11
【问题描述】:

我有一个 3 层的项目。 UI、业务层和数据层。

UI 调用 BL。 BL 呼叫 DL。 DL 执行数据库操作。就这么简单。

我想对我的 BL 方法进行单元测试,所以我对其进行了一些更改,现在我在 BL 构造函数中接受 DL 作为参数,以便我可以创建 DL 的 Mock 对象。

这让我改变了我的 UI 层,因为我的 UI 调用了我的 BL,并且根据架构规则,如果我将我的 DL 的引用添加到我的 UI,我认为这不是一个好的设计。

有人可以提出更好的方法吗?我需要更改架构还是我在这里做错了什么?我可以在这里介绍 Facade Manager 吗?非常感谢您的建议示例。

--编辑--

代码如下:

在 BL 中:

    public MyBusinessLayer()
    {

    }
    //To pass mock object of WCF Service
    public MyBusinessLayer(ISomeServices svc)
    {
        someServiceRef = svc;
    }

    //To pass mock object of Data Layer.
    public MyBusinessLayer(ISomeDataLayer dl)
    {
        someDlRef = dl;
    }

在用户界面中:

//To do this i have to add DL reference to UI
MyBusinessLater b = new MyBusinessLayer(new ISomeService());

【问题讨论】:

  • 展示一些你在做什么的代码怎么样?
  • 我可以创建 Manager 类并在 UI 层中引用它并向它添加 BL 和 DL 引用,但我再次对将 BL 和 DL 引用添加到同一个(管理器)类感到不舒服。我希望 DL 仅在 BL 中被引用。

标签: c# design-patterns architecture


【解决方案1】:

IoC 非常适合这项工作。你的 BL 应该只依赖一个可以获取它需要的数据的接口。然后,使用 IoC,向接口注册实际的 DB 实现。然后,UI 应该被注入接口的 BL。因此,当应用启动时,您注册了所有依赖项,并且只是将 BL 接口注入到 UI 中,因此 UI 不知道实际的 BL 实现依赖于 DL 接口这一事实。

这只是我在网上找到的一个例子。只需谷歌 C# IOC 或 C# 依赖注入。 http://www.dotnetspark.com/kb/266-inversion-control-ioc-and-dependency-injection.aspx

【讨论】:

  • 我知道 IoC,但问题是我不能在项目中使用它。我知道这太糟糕了,但在那里什么也做不了。
  • @Asdfg - 您已经在使用 IoC(例如将 ISomeServices 传递给 MyBusinessLayer 构造函数)。您不必使用 IoC 容器框架。
  • @TrueWill - 我能够做到这一点,因为我的 ISomeServices 接口位于 BL 中。问题是我的 ISomeDataLayer 接口位于 DL 中。为了使用它,它说我必须将 DataLayer 引用添加到我的 UI。我是否需要为 ISomeDataLayer 界面创建单独的项目并将其添加到我的 UI 层?这不会被视为在 UI 中添加 DL 引用吗?
  • @Asdfg - 通常,您需要为共享接口创建一个单独的项目。如果您有理由确定实现不会更改并且您主要是为了可测试性而这样做,那么您现在可以将接口留在 DL 中。向 UI 添加接口与添加具体的 DL 类引用不同。也就是说,我认为您想要的是@BFree 建议的接口 BL。所以BL得到DL接口,UI只得到BL接口。
  • @TrueWill - 好的。这就是我所做的。我从 DL 项目中删除了 DL 接口,并将其放在单独的程序集中,并从我的 UI 和我的单元测试项目中引用它。问题已解决。正如您所说,引用接口与添加具体 DL 不同,我认为我很好。我会对我的 BL 做同样的事情。如果我走错了路,请告诉我。非常感谢您的帮助。非常感谢。
【解决方案2】:

一种方法是将所有数据类型放在一个单独的 dll 中。

然后从 UI、BL 和 DAL 中引用这个 dll。

那么 UI 就不需要引用 DAL。

【讨论】:

    【解决方案3】:

    @BFree 的回答是正确的;我只是回答澄清我的cmets。以下是我的推荐(我相信这与@BFree 推荐的相同):

    public class MyBusinessLayer : IBusinessLayer
    {
        public MyBusinessLayer(ISomeDataLayer dl, ISomeServices svc) {}
    }
    
    public class MyUI
    {
        public MyUI(IBusinessLayer bl) {}
    }
    

    无论您使用的是 MVC、MVVM 还是其他任何东西,某处都在创建您的用户界面(或其控制器)。该方法可以了解所有内容,因为它将所有内容连接起来。其他的都只知道接口。

    我更关心对其他层(耦合)中具体类型的引用,而不是项目中的程序集引用。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-10-28
      • 1970-01-01
      • 1970-01-01
      • 2012-11-11
      • 2012-12-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多