Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/25.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# .NET配置-如何创建易于理解的配置_C#_.net_Dependency Injection_Configuration - Fatal编程技术网

C# .NET配置-如何创建易于理解的配置

C# .NET配置-如何创建易于理解的配置,c#,.net,dependency-injection,configuration,C#,.net,Dependency Injection,Configuration,我通常使用一些配置创建类,这些配置通过构造函数注入到类中。我还使用选项模式 例如,我可以有一个类: 公共类MyService:IMyServce { 私有只读MyServiceOptions\u选项; 私有只读依赖项_依赖项; public MyService(IOOptions、ISomeDependency) { _选项=选项.值; _依赖=依赖; } //... } 通常,我会创建一些扩展来将其添加到IServiceCollection: public static IServiceCo

我通常使用一些配置创建类,这些配置通过构造函数注入到类中。我还使用选项模式

例如,我可以有一个类:

公共类MyService:IMyServce
{
私有只读MyServiceOptions\u选项;
私有只读依赖项_依赖项;
public MyService(IOOptions、ISomeDependency)
{
_选项=选项.值;
_依赖=依赖;
}
//...
}
通常,我会创建一些扩展来将其添加到IServiceCollection:

public static IServiceCollection AddMyService(此IServiceCollection服务、IConfiguration配置、string keyVaultKey、bool iProduction)
{
services.AddSignleton();
services.AddSignleton();
services.Configure(configuration.GetSection(“MyService”));
Configure(configuration.GetSection(“SomeDependency”);
如果(i生产)
{
//使用KeyVault密钥从密钥库加载一些机密
}
}
我有一些担心:

  • 扩展方法读取
    IConfiguration
    对象的特定部分。代码用户必须使用此特定方法才能知道如何配置其应用程序,以便正确使用
    MyService
    。我认为这并不是最理想的。另一个问题是,我使用了部分的一些特定硬编码名称(“MyService”)。如果其他服务也依赖于相同的配置部分(我的意思是,用户可能使用两个不同的NuGet包,其中两个包都定义了扩展方法,其中使用了相同的配置部分),该怎么办。怎么处理

  • 用户应在Azure KeyVault中存储一些秘密值


  • 你对此有什么想法?我的目的是使我的服务尽可能易于配置,过程也应尽可能易于理解。

    我遵循类似的模式,并与您分享您的担忧。我不知道我能让它变得容易,但我总是遵循一些规则,这些规则往往会让它变得“更容易”

  • 仅依赖于特定于我的服务并包含在该服务命名空间中的选项。外部依赖项应该有自己的选项和自己的扩展来注册该服务(包括自己的选项)
  • 选项类应尽可能提供默认值,并记录在案,以让用户知道如何与您的服务交互(包括来自某些
    i配置的必需设置)
  • 我通常使用选项类本身的名称,使用nameof来避免字符串文字
  • 您的服务扩展不应该关心如何提供IConfiguration(例如,它不应该知道某些设置来自密钥库)。我通常在程序中加载配置源时做出此决定,并使用环境设置来了解要使用的配置提供程序

    public static IServiceCollection AddMyService(this IServiceCollection services, IConfiguration configuration, string keyVaultKey, bool isProduction)
    {
        services.AddSignleton<IMyService, MyService>();
        services.AddSignleton<ISomeDependency, SomeDependency>();
    
        services.Configure<MyServiceOptions>(configuration.GetSection(nameof(MyServiceOptions)));
        services.Configure<SomeDependencyOptions>(configuration.GetSection(nameof(SomeDependencyOptions)));
    }
    
    public static IHostBuilder CreateHostBuilder(string[] args) =>
        Host.CreateDefaultBuilder(args)
            .ConfigureAppConfiguration((context, config) =>
            {
                if (context.HostingEnvironment.IsProduction())
                {
                    // Add your key vault stuff here
                }
            })
            .ConfigureWebHostDefaults(webBuilder =>
            {
                webBuilder.UseStartup<Startup>();
            });
    
    public static IServiceCollection AddMyService(此IServiceCollection服务、IConfiguration配置、string keyVaultKey、bool iProduction)
    {
    services.AddSignleton();
    services.AddSignleton();
    Configure(configuration.GetSection(nameof(myservicecoptions));
    Configure(configuration.GetSection(nameof(SomeDependencyOptions));
    }
    公共静态IHostBuilder CreateHostBuilder(字符串[]args)=>
    Host.CreateDefaultBuilder(args)
    .ConfigureAppConfiguration((上下文,配置)=>
    {
    if(context.HostingEnvironment.IsProduction())
    {
    //在此处添加您的密钥库内容
    }
    })
    .ConfigureWebHostDefaults(webBuilder=>
    {
    webBuilder.UseStartup();
    });
    

  • 我认为简单的答案是:将服务设计为易于配置并提供文档

    更长的答案

    关于第1点:

    在这个过程中有两个开发人员。服务的生产者(编写MyService的人)和服务的消费者(将服务注入其应用程序的人)。在这种情况下,同一个人,但从逻辑上讲,是两个不同的人

    生产者不关心如何在调用应用程序中实现配置。他们只关心使服务易于使用和记录(以及使其正确工作等)

    应向消费者提供文档,以确保他们了解如何使用服务。不应该期望他们查看服务的源代码来找出如何使其工作

    这取决于消费者如何存储此配置。他们可以自由选择他们所称的配置部分。如果他们希望两个服务使用相同的配置部分,那么没有问题

    services.Configure<MyService1Options>(configuration.GetSection("MyService"));
    services.Configure<MyService2Options>(configuration.GetSection("MyService"));
    
    services.Configure(configuration.GetSection(“MyService”);
    services.Configure(configuration.GetSection(“MyService”));
    
    如果他们想要两个使用不同配置部分的服务,这同样取决于他们

    services.Configure<MyService1Options>(configuration.GetSection("MyService1"));
    services.Configure<MyService2Options>(configuration.GetSection("MyService2"));
    
    services.Configure(configuration.GetSection(“MyService1”);
    services.Configure(configuration.GetSection(“MyService2”);
    
    关于第2点:


    使用Azure Key Vault是消费者的一项实施决策。他们不需要使用它。

    我想你可以在softwareengineering.stackexchange.com上找到更好的答案