C# 具有非DI和DI参数的构造函数

C# 具有非DI和DI参数的构造函数,c#,dependency-injection,asp.net-core,C#,Dependency Injection,Asp.net Core,我正在创建一个需要一些配置参数和记录器的服务。以下是我的服务的构造函数: public StorageProvider(string directory, ILogger<StorageProvider> logger) publicstorageprovider(字符串目录,ILogger记录器) 我刚刚添加了记录器。我曾经在startup.cs中这样初始化它: services.AddSingleton<IStorageProvider>( new Sto

我正在创建一个需要一些配置参数和记录器的服务。以下是我的服务的构造函数:

public StorageProvider(string directory, ILogger<StorageProvider> logger)
publicstorageprovider(字符串目录,ILogger记录器)
我刚刚添加了记录器。我曾经在startup.cs中这样初始化它:

services.AddSingleton<IStorageProvider>(
    new StorageProvider(Configuration["TempStorage.Path"]));
services.AddSingleton(
新的StorageProvider(配置[“TempStorage.Path”]);

directory
参数来自配置文件,记录器将被设置。如何设置我的
IStorageProvider

使用Tratcher在注释中建议的
选项
模式。阅读更多的文章

基本上,您定义一个类来保存所需的值:

public class StorageProviderOptions
{
    public string TempStoragePath { get; set; }
}
然后在
ConfigureServices
中注册类型:

services.Configure<StorageProviderOptions>();
最后,确保配置源中有一个元素与
TempStoragePath
名称匹配。或者,您可以使用以下代码在
ConfigureServices
中注册该选项:

services.Configure<ServiceProviderOptions>(o => o.TempStoragePath = "temp");
services.Configure(o=>o.TempStoragePath=“temp”);

您应该执行以下操作:

  • 将配置值
    TempStorage:Path
    包装到它自己的配置类中,例如
    StorageProviderSettings
  • StorageProvider
    依赖于新的配置类
  • 将该配置类作为singleton注册到ASP.NET配置系统中
例如:

public sealed class StorageProviderSettings
{
    public readonly string TempStoragePath;

    public StorageProviderSettings(string tempStoragePath)
    {
        if (string.IsNullOrWhiteSpace(tempStoragePath))
            throw new ArgumentException(nameof(tempStoragePath));
        this.TempStoragePath = tempStoragePath;
    }
}

public sealed class StorageProvider : IStorageProvider
{
    public StorageProvider(
        StorageProviderSettings settings, ILogger<StorageProvider> logger)
    {
        // ...
    }
}

// Registration
services.AddSingleton(new StorageProviderSettings(Configuration["TempStorage.Path"]));
services.AddSingleton<IStorageProvider, StorageProvider>();
公共密封类StorageProviderSettings
{
公共只读字符串TempStoragePath;
公共存储提供程序设置(字符串tempStoragePath)
{
if(string.IsNullOrWhiteSpace(tempStoragePath))
抛出新ArgumentException(nameof(tempStoragePath));
this.TempStoragePath=TempStoragePath;
}
}
公共密封类StorageProvider:IStorageProvider
{
公共存储提供商(
StorageProviderSettings设置,ILogger记录器)
{
// ...
}
}
//登记
services.AddSingleton(新的StorageProviderSettings(配置[“TempStorage.Path]”);
services.AddSingleton();

您如何注册
ILogger
?那也是单身吗?如果是这样,请将同一实例传递给
ILogger
注册到
StorageProvider
构造。执行此操作时,将包含记录器:WebHost.CreateDefaultBuilder(args)(请参阅)您可以使用
IOptions
插入目录路径。阅读文档中的使用配置我不确定是否完全理解您的意思,但要明确的是:
ILogger
不需要
StorageProvider
的实际实例,如果您这样想的话。type param用于区分日志条目,实际上与之无关。正如前面所解释的,将
IOptions
注入应用程序组件是一个坏主意。有趣的是,我还没有读过这篇文章。既然这样做了,我倾向于同意那篇文章的评估(尽管目前IOptions仍然是解决这个问题的有文档记录的MSFT解决方案)。但众所周知,微软记录了一些东西(甚至构建了一些东西)这一事实并不能使它立即成为一个好的解决方案:)的确,这是事实。:)
public sealed class StorageProviderSettings
{
    public readonly string TempStoragePath;

    public StorageProviderSettings(string tempStoragePath)
    {
        if (string.IsNullOrWhiteSpace(tempStoragePath))
            throw new ArgumentException(nameof(tempStoragePath));
        this.TempStoragePath = tempStoragePath;
    }
}

public sealed class StorageProvider : IStorageProvider
{
    public StorageProvider(
        StorageProviderSettings settings, ILogger<StorageProvider> logger)
    {
        // ...
    }
}

// Registration
services.AddSingleton(new StorageProviderSettings(Configuration["TempStorage.Path"]));
services.AddSingleton<IStorageProvider, StorageProvider>();