何种设计方法允许表示层根据配置选择性地依赖本地DLL调用或WCF服务调用

本文关键字:调用 依赖 服务 DLL 选择性 WCF 配置 方法 表示层 何种 | 更新日期: 2023-09-27 18:10:24

我正在设计一个内部web应用程序,将有3层:

  1. 演讲(MVC)
  2. 服务,工作流
  3. 数据访问/持久化存储

最初,应用程序将在一个简单的两层环境中运行。然而,在某种程度上,我希望它能够轻松地扩展/缩放到3层,每层一个。

我可以简单地使用WCF服务的服务层,但我发现相当大的开销调用,即使使用命名管道(IIS托管)。我更愿意有一个解决方案,可以配置为使用2层风格的本地DLL调用,但使用3层风格的WCF调用。

我相信DI在这里工作得很好,但我正在寻找这样做的人来解释这种方法的任何潜在缺陷

何种设计方法允许表示层根据配置选择性地依赖本地DLL调用或WCF服务调用

我认为你的DI建议已经成功了。此外,存储库模式在这里也会有所帮助。

首先,编写一个接口,该接口将封装对尚未定义的第三层的所有调用。这将是我们编写代码的契约(不要将其与WCF数据契约混淆,它们将单独存在)。

//use a more descriptive name of course
public interface IThirdLayer {
    void SomeRepositoryMethod(SomeArg arg);
}

然后编写该接口的两个具体实现,一个用于本地存储库(可能是SQL调用),一个用于远程存储库(可能使用服务引用或ChannelFactory类)。这些类将封装第三层的所有逻辑,

在任何希望使用该层的类中,只需传递IThirdLayer的实现:

public class SomeBusinessLogicClass {
    private readonly IThirdLayer _repository;
    //constructor injection for the win!
    public SomeBusinessLogicClass(IThirdLayer repository) {
        _repository = repository;
    }
    public void SomeBusinessLogicMethod(SomeArgs arg) {
        //example use of repository
        _repository.SomeMethod(arg);
    }
}

因为我们是针对一个契约(接口IThirdLayer)进行编码,并通过构造函数提供该契约,所以我们的业务逻辑层不需要知道第三层实现的任何细节,即它是WCF、SQL还是基于文件的。

你也可以使用你最喜欢的依赖注入容器来帮助你,这将提供你需要的配置。我个人使用微软的Unity,但有很多选项可用,所以我不会发布示例配置。

希望对你有帮助。

我忘了用这种方法来平息你对陷阱的恐惧。除了必须编写一些额外的类来实现所需的抽象之外,实际上没有其他陷阱。这是一种你可以在各种场景中反复重复的模式,而不仅仅是这个。针对接口编写代码始终是一个很好的实践,即使在您的生产代码中只会有一个该接口的具体实现。

为什么会这样?原因在于,如果将来需要的话,可以很容易地切换实现,而且还因为在单元测试中经常会有上述接口的另一个实现——无论是手写的模拟实现,还是由模拟框架动态生成的实现(我使用Rhino mock)。因此,这种方法的另一个好处是可测试性,在单元测试中,您提供了Repository接口的特定于测试的实现——这意味着您的业务逻辑可以独立测试,而不依赖于具体的类。