ASP.NET Core MvcJsonOptions dependency injection without modified closure?

两盒软妹~` 提交于 2019-12-23 05:49:12

问题


(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.)

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:

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.

Is there an alternative to achieve the same dependency injection without using modified closure?


回答1:


You can likely postpone the assignment to .Configure method, it should work.

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.

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).

But you may want consider to directly instantiate the ITraceWriter and pass it as instance to the IoC container, such as

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:

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.



来源:https://stackoverflow.com/questions/45826530/asp-net-core-mvcjsonoptions-dependency-injection-without-modified-closure

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!