Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/design-patterns/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何避免在UI层中引用数据层?_C#_Design Patterns_Architecture - Fatal编程技术网

C# 如何避免在UI层中引用数据层?

C# 如何避免在UI层中引用数据层?,c#,design-patterns,architecture,C#,Design Patterns,Architecture,我有一个3层的项目。用户界面、业务层和数据层 UI调用BL。BL调用DL。DL负责数据库操作。就这么简单 我想对我的BL方法进行单元测试,所以我对它做了一些修改,现在我接受DL作为BL构造函数中的一个参数,这样我就可以创建DL的模拟对象 这使得我在UI调用BL时更改了UI层,根据架构规则,如果我将DL的引用添加到UI中,我认为这不是一个好的设计 有人能提出更好的办法吗?我是否需要改变架构,或者我在这里做错了什么?我可以在这里介绍门面经理吗?请举例说明你的建议,我们将不胜感激 --编辑-- 代码如

我有一个3层的项目。用户界面、业务层和数据层

UI调用BL。BL调用DL。DL负责数据库操作。就这么简单

我想对我的BL方法进行单元测试,所以我对它做了一些修改,现在我接受DL作为BL构造函数中的一个参数,这样我就可以创建DL的模拟对象

这使得我在UI调用BL时更改了UI层,根据架构规则,如果我将DL的引用添加到UI中,我认为这不是一个好的设计

有人能提出更好的办法吗?我是否需要改变架构,或者我在这里做错了什么?我可以在这里介绍门面经理吗?请举例说明你的建议,我们将不胜感激

--编辑--

代码如下:

在《基本法》中:

    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;
    }
在UI中:

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

国际奥委会非常适合这项工作。你的BL应该只依赖一个能获取它所需数据的接口。然后,使用IoC,向接口注册实际的DB实现。然后UI应该被注入接口BL。因此,当应用程序启动时,您注册所有依赖项,然后只将BL接口注入UI,因此UI不知道实际的BL实现依赖于DL接口

这只是我在网上找到的一个例子。只需谷歌搜索C#IOC或C#依赖注入。
一种方法是将所有数据类型放在一个单独的dll中

然后从UI、BL和DAL引用此dll


那么用户界面就不需要引用DAL了。

@BFree的答案是正确的;我只是想澄清我的评论。以下是我的建议(我相信与@BFree的建议相同):

无论您使用的是MVC、MVVM还是其他什么,都会有某种东西在创建您的用户界面(或其控制器)。这种方法可以了解一切,因为它将一切联系起来。其他一切都只知道接口


我更关心其他层中对混凝土类型的引用(耦合)而不是关于项目中的程序集引用。

如何显示您正在执行的一些代码?我可以创建Manager类,并在UI层中引用它,并向其添加BL和DL引用,但同样地,将BL和DL引用添加到同一(Manager)类中,我感到不舒服。我希望DL只在BL中引用。我知道IoC,但问题是我不能在项目中使用它。我知道这太糟糕了,但在那里什么都做不了。@Asdfg-您已经在使用IoC(例如,将服务传递给MyBusinessLayer构造函数)。您不必使用IoC容器框架。@TrueWill-我可以这样做,因为我的ISomeServices接口位于BL中。问题是我的ISomeDataLayer接口位于DL中。为了使用它,它说我必须将数据层引用添加到我的UI中。我是否需要为数据层接口创建单独的项目并将其添加到我的UI层?这不会被视为向UI添加DL引用吗?@Asdfg-通常,您需要为共享接口创建一个单独的项目。如果您合理地确定实现不会改变,并且主要是为了可测试性,那么现在可以将接口留在DL中。向UI添加接口与添加具体的DL类引用不同。也就是说,我认为您需要的是@BFree建议的接口BL。所以BL得到DL接口,UI只得到BL接口。@TrueWill-Ok。这就是我所做的。我从DL项目中删除DL接口,并将其放在单独的程序集中,并从UI和单元测试项目中引用它。问题解决了。正如您所说,引用接口与添加具体的DL不同,我认为我很好。我会对我的BL做同样的事情。如果我走错了方向,请一定告诉我。非常感谢你的帮助。非常感谢。
public class MyBusinessLayer : IBusinessLayer
{
    public MyBusinessLayer(ISomeDataLayer dl, ISomeServices svc) {}
}

public class MyUI
{
    public MyUI(IBusinessLayer bl) {}
}