简体   繁体   English

没有修改闭包的ASP.NET Core MvcJsonOptions依赖项注入?

[英]ASP.NET Core MvcJsonOptions dependency injection without modified closure?

(This question is similar to ASP.NET Core MvcOptions dependency injection without modified closure? However, I struggle to apply the solution of that question to this one.) (此问题类似于没有修改的闭包的ASP.NET Core MvcOptions依赖项注入。但是,我很难将此问题的解决方案应用于此问题。)

In my ASP.NET Core 1.1.3 project, I currently inject an ITraceWriter dependency into MvcJsonOptions in the ConfigureServices method in the following way: 在我的ASP.NET Core 1.1.3项目中,我目前通过以下方式在ConfigureServices方法中将ITraceWriter依赖项注入MvcJsonOptions中:

public override IServiceProvider ConfigureServices(IServiceCollection services)
{
    services.AddProjectSpecificStuff();

    ITraceWriter traceWriter = null;

    services.AddMvc().AddJsonOptions(options =>
    {
        options.SerializerSettings.TraceWriter = traceWriter;
    });

    var provider = base.ConfigureServices(services);

    traceWriter = provider.GetService<ITraceWriter>();

    return provider;
}

This works, but causes code analyzers such as ReSharper to complain about access to modified closure. 这可以工作,但是会使诸如ReSharper之类的代码分析器抱怨访问已修改的闭包。

Is there an alternative to achieve the same dependency injection without using modified closure? 是否有替代方法可以在不使用修改的闭包的情况下实现相同的依赖项注入?

You can likely postpone the assignment to .Configure method, it should work. 您可以将分配推迟到.Configure方法,它应该可以工作。

public override IServiceProvider ConfigureServices(IServiceCollection services)
{
    services.AddProjectSpecificStuff();

    ITraceWriter traceWriter = null;

    services.AddMvc().AddJsonOptions(options =>
    {
        ...
        // other options here
    });

    return base.ConfigureServices(services);
}

public void Configure(IApplicationBuilder app, ITraceWriter traceWriter, IOptions<MvcJsonOptions> jsonOptions)
{
    services.AddMvc().AddJsonOptions(options =>
    {
        options.SerializerSettings.TraceWriter = provider.GetService<ITraceWriter>();
    });
}

This will work for as long as your dependencies (like IOptions<MvcJsonOptions> and ITraceWriter are singletons. 只要您的依赖项(例如IOptions<MvcJsonOptions>ITraceWriter是单例),就可以使用它。

Word of warning 警告词

However, this behavior may change in future, as some plans/ideas were on the ASP.NET Core GitHub issues, that the ASP.NET Core may change this to create an implicitly scoped context which is used during .Configure , it may or may not break the above code (if it ever comes). 但是,此行为将来可能会更改,因为某些计划/想法是关于ASP.NET Core GitHub的问题,因此ASP.NET Core可能会对此进行更改以创建隐式范围内的上下文,该上下文将在.Configure期间使用,它可能会或可能会不要破坏上面的代码(如果有的话)。

But you may want consider to directly instantiate the ITraceWriter and pass it as instance to the IoC container, such as 但是您可能需要考虑直接实例化ITraceWriter并将其作为实例传递给IoC容器,例如

ITraceWriter traceWriter = new TraceWriter(/* other dependencies */);
services.AddSingleton<ITraceWriter>(traceWriter);

It's okay to compose it in the composition root, as long as it's a singleton. 只要是单例,就可以在合成根中进行合成。

Or alternatively you choose this brute and somewhat ugly solution and instantiate MvcJsonOptions via factory method: 或者,您也可以选择这种MvcJsonOptions且有些丑陋的解决方案,并通过工厂方法实例化MvcJsonOptions

services.AddSingleton<IOptions<MvcJsonOptions>>(provider => Options.Create(new MvcJsonOptions
{
    SerializerSettings.TraceWriter = provider.GetService<ITraceWriter>()
}));

Then it's pretty ugly (though you could hide that behind an extension method) and you may override defaults set by the mddleware/extension method. 然后这很丑陋(尽管您可以将其隐藏在扩展方法后面),并且可以覆盖mddleware / extension方法设置的默认值。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM