1

我有一个使用接口IBackend与后端通信的应用程序。在生产环境中我希望使用类ProdBackend : IBackend作为接口的实现。在我希望使用的测试环境中TestBackend : IBackend

应用程序被打包成一个 zip 文件,它必须独立于它是部署在 prod 环境还是 test 环境中。

如何使应用程序IBackend根据其部署的环境使用不同的实现?

我可以通过在两个环境中安装不同的 .dll 并将类命名相同来做到这一点吗?

更新 11:12 - 15/1:打包的应用程序不允许包含 prod 实现,即ProdBackend : IBackend. ProdBackend : IBackend所以应用程序在编译时并不知道。

4

4 回答 4

1

根据您的设置,有很多方法可以做到这一点。我能想到这些:

  1. 机器名称: 如果您知道测试服务器的服务器名称(或约定),您可以基于Envirnoment.MachineName.
  2. 插件:如果您使用插件模型(通过构建一个包含 contains 的程序集ProdBackendTestBackend您可以在部署应用程序时做出决定。您可以通过 IOC 容器用于连接依赖项的插件目录来做到这一点(或其他方式)。
  3. 配置:您可以使用配置文件中的值来确定环境,然后使用该信息在两个实现之间进行选择。然后,在部署到 prod 环境时,您可以相应地调整配置文件 ( app.config)。
于 2013-01-15T10:07:58.693 回答
0

提供具有相同接口的不同实现的不同 DLL 可以正常工作。

一个更优雅的解决方案是这样做,但添加一个服务定位器来提供您需要的实现。然后,您可以配置服务定位器以根据您运行的平台返回一个实现。

有很多服务定位器,但是一个简单的可以在 Mono 支持的所有平台上运行的服务定位器是TinyIOC

于 2013-01-15T10:13:45.180 回答
0

测试环境的全部意义在于让您尽可能合理地确定,当您将某些东西部署到生产环境时,它将正常工作。如果您有一组在测试中执行的代码和另一组在部署到生产时执行的代码,您将如何实现该目标?

从本质上讲,从代码角度来看,测试和生产之间的区别应该只是配置(不同的数据库连接,可能更详细的测试日志记录等)。否则,本质上,您是在将未经测试的代码部署到生产环境中,在我看来,这是为可能的灾难播下的种子。

于 2013-01-15T11:25:09.183 回答
0

有一个概念:上下文绑定——几乎所有的依赖注入容器都实现了它。实际上,这意味着您可以将条件添加到绑定中。这是使用

定义“生产”环境条件

例如 byEnvironment.MachineName或任何其他适合您的方式:

private static readonly Func<bool> IsCurrentEnvironmentProduction = 
   () => Environment.MachineName == "Production.Server";

为不同的环境定义绑定

public static IKernel InitializeKernel() 
{ 
    var kernel = new StandardKernel();

    // binding for production
    kernel
        .Bind<IBackend>()
        .To<ProdBackend>()
        .When(request => IsCurrentEnvironmentProduction());

    // binding for test environment
    kernel
        .Bind<IBackend>()
        .To<TestBackend>()
        .When(request => !IsCurrentEnvironmentProduction());

    return kernel; 
}

解析实例取决于环境

DI 容器将为您完成所有工作

var backend = kernel.Get<IBackend>();

完整样本可在此处获得

关于 Mono 的备注

根据Ninject 下载,有一个 Mono 版本,但您也可以在其他 DI 容器中实现相同的功能

于 2013-01-15T12:49:30.090 回答