Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/310.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# 根据环境更改接口的实现_C#_Dependency Injection_Mono_Ninject - Fatal编程技术网

C# 根据环境更改接口的实现

C# 根据环境更改接口的实现,c#,dependency-injection,mono,ninject,C#,Dependency Injection,Mono,Ninject,我有一个应用程序,它使用接口IBackend与后端进行通信。在生产环境中,我希望使用classprodbend:IBackend作为接口的实现。在测试环境中,我希望使用TestBackend:IBackend 应用程序被打包到一个zip文件中,该文件必须独立于它是部署在prod环境还是测试环境中 如何使应用程序根据部署环境使用不同的IBackend实现 我可以通过在两个环境中安装不同的.dll并将类命名为相同的名称来实现这一点吗 更新11:12-15/1: 打包的应用程序不允许包含prod实现,

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

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

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

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

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

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

  • 机器名:如果您知道测试服务器的服务器名(或约定),则可以基于
    Envirnoment.MachineName
    重新建立依赖关系
  • 插件:如果使用插件模型(通过构建一个包含
    prodbend
    的程序集和一个包含
    TestBackend
    的程序集),您可以在部署应用程序时做出决定。您可以通过拥有一个插件目录来实现这一点,您的IOC容器将使用该目录连接依赖项(或其他方式)
  • 配置:您可以使用配置文件中的值来确定环境,然后使用该信息在两种实现之间进行选择。然后,在部署到产品环境时,您可以相应地调整配置文件(
    app.config

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

  • 机器名:如果您知道测试服务器的服务器名(或约定),则可以基于
    Envirnoment.MachineName
    重新建立依赖关系
  • 插件:如果使用插件模型(通过构建一个包含
    prodbend
    的程序集和一个包含
    TestBackend
    的程序集),您可以在部署应用程序时做出决定。您可以通过拥有一个插件目录来实现这一点,您的IOC容器将使用该目录连接依赖项(或其他方式)
  • 配置:您可以使用配置文件中的值来确定环境,然后使用该信息在两种实现之间进行选择。然后,在部署到产品环境时,您可以相应地调整配置文件(
    app.config

  • 为不同的DLL提供相同接口的不同实现会很好

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


    有很多服务定位器,但是一个简单的定位器可以在Mono支持的所有平台上运行,它可以为不同的DLL提供相同接口的不同实现

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


    有很多服务定位器,但一个简单的定位器可以在Mono支持的所有平台上运行,它就是测试环境的全部要点是允许您尽可能合理地确保当您将某些东西部署到生产环境时,它会正常工作部署到生产环境时执行的一组不同的代码,您是如何实现这一目标的


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

    测试环境的整个要点是让您尽可能合理地确定,当您将某些东西部署到生产环境中时,它将正常工作。如果您有一组代码在测试时执行的,以及部署到生产环境时执行的一组不同的代码,您是如何实现这一目标的

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

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

    定义“生产”环境条件 例如,通过
    环境.MachineName
    或任何其他适合您的方式:

    private static readonly Func<bool> IsCurrentEnvironmentProduction = 
       () => Environment.MachineName == "Production.Server";
    
    private静态只读函数IsCurrentEnvironmentProduction=
    ()=>Environment.MachineName==“Production.Server”;
    
    为不同的环境定义绑定
    公共静态IKernel InitializeKernel()
    { 
    var kernel=新的标准内核();
    //生产用装订
    内核
    .Bind()
    .至()
    .When(请求=>IsCurrentEnvironmentProduction());
    //测试环境的绑定
    内核
    .Bind()
    .至()
    .When(请求=>!IsCurrentEnvironmentProduction());
    
    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; 
    }
    
    var backend = kernel.Get<IBackend>();