【问题标题】:c# Inject settings in aspnet core external libraryc#在aspnet核心外部库中注入设置
【发布时间】:2020-02-05 09:43:10
【问题描述】:

我有一个项目,其入口点是 ASP.NET Core API,基础设施项目是 MongoDB 客户端。我有一个问题,我会在带有 mongo 客户端的项目中注入我的接口 IDatabaseSettings(即在一个普通项目中),所以我在我的主项目中创建具体类型,如下所示:

public class MongoSettings : IDatabaseSettings
{
    private const string Mongo = "Mongo";
    private static IConfiguration _configuration;

    public LogMongoSettings(IConfiguration configuration)
    {
        _configuration = configuration;
    }

    public string ConnectionString { get; } = _configuration.GetValue<string>($"{Mongo}:ConnectionString");
    public string DatabaseName { get; } = _configuration.GetValue<string>($"{Mongo}:Database");
    public string Username { get; } = _configuration.GetValue<string>($"{Mongo}:Username") ?? string.Empty;
    public string Password { get; } = _configuration.GetValue<string>($"{Mongo}:Password") ?? string.Empty;
}

问题在于 _configuration 始终为 null,并且此代码引发异常。 我使用 SimpleInjector 容器,我的启动项目是这样的:

public class Startup
{

    private static readonly Container Container = new Container();
    private static readonly Assembly LogReaderAssembly = Assembly.Load("LogReader.IdP");
    private static readonly Assembly MongoLogReaderAssembly = Assembly.Load("LogReader.Mongo");

    public Startup(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public IConfiguration Configuration { get; }

    // This method gets called by the runtime. Use this method to add services to the container.
    // For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddControllers();
        services.AddSimpleInjector(Container, options =>
        {
            options.AddAspNetCore()
                .AddControllerActivation();
            options.AddLogging();
        });
        services.AddSwaggerGen(options =>
        {
            options.SwaggerDoc("LogReader", new OpenApiInfo
            {
                Version = "V1"
            });
        });

       InitializeContainer();
    }


    private static void InitializeContainer()
    {
        Container.RegisterSingleton<IDatabaseClient, DatabaseClient>();
        Container.Register<IFileRepositoryReader, TraceFileRepositoryReader>();
        Container.Register(typeof(IRepositoryReader<>), MongoLogReaderAssembly);
        Container.RegisterSingleton(() => Container.GetInstance<MapperProvider>().GetMapper());
        Container.Register(typeof(IQueryHandler<,>), LogReaderAssembly);
        Container.Register<IDatabaseSettings, MongoSettings>();
    }

    // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        app.UseSimpleInjector(Container);

        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }
        app.UseRouting();
        app.UseEndpoints(endpoints =>
        {
            endpoints.MapControllers();

        });
        app.UseSwagger();
        Container.Verify(VerificationOption.VerifyAndDiagnose);
    }
}

为什么会这样?问题是什么? 我不会在我的 Mongo 客户端中使用 IOptionMonitor,因为我不认为这个类依赖于具体的 TOptions。 有没有更好的解决问题的方法? 谢谢。

【问题讨论】:

  • Simple Injector never 将 null 值注入到构造函数中,因此我可以得出结论,MongoSettingsnot 解决/创建的简单的注射器。尝试在 MongoSettings ctor 中设置断点,以查看是谁创建了它以及触发了它的创建。

标签: c# asp.net-core configuration simple-injector


【解决方案1】:

最后,我用这段代码解决了问题:

public class MongoDatabaseSettings : IDatabaseSettings
{
    private const string Mongo = "Mongo:";

    public MongoDatabaseSettings(IConfiguration configuration)
    {
        Host = configuration.GetValue<string>($"{Mongo}{nameof(Host)}");
        Port = configuration.GetValue<int>($"{Mongo}{nameof(Port)}");
        DatabaseName = configuration.GetValue<string>($"{Mongo}{nameof(DatabaseName)}");
        Username = configuration.GetValue<string>($"{Mongo}{nameof(Username)}");
        Password = configuration.GetValue<string>($"{Mongo}{nameof(Password)}");
    }

    public string Host { get; }
    public int Port { get; } 
    public string DatabaseName { get; } 
    public string Username { get; } 
    public string Password { get; } 
}

我不明白为什么在这种情况下属性被正确初始化,而不是原始问题代码不起作用。 你知道为什么会这样吗?谢谢

【讨论】:

    猜你喜欢
    • 2019-06-21
    • 1970-01-01
    • 2020-10-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-10-06
    • 2018-01-03
    相关资源
    最近更新 更多