本文介绍了ConfigureServices中的请求实例的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

ConfigureServices内,我正在设置许多服务(这可行).我尝试使用相同的方法(针对Razor)配置自定义文件提供程序.看起来像这样:

Within ConfigureServices I'm setting up a number of services (this works). In the same method I'm trying to configure a custom file provider (for Razor). It looks like this:

services.AddMvc()
        .AddRazorOptions(options =>
        {
            options.FileProvider = new CustomFileProvider(???);
        });

CustomFileProvider有一些依赖项(都已配置),但是在配置完所有服务之后,如何立即要求DI给我一个CustomFileProvider实例?

CustomFileProvider has a few dependencies (that are all configured), but how can I ask the DI to give me an instance of CustomFileProvider right after all the services have been configured?

从我的角度来看,DI仅注入构造函数,但就我而言,我需要一个请在此处给我CustomFileProvider的实例"选项.

From what I can see the DI only injects in constructors, but in my case I need a "please give me an instance of CustomFileProvider right here" option.

推荐答案

如果您希望能够在配置某些选项的同时从容器中解析服务,则需要利用IConfigureOptions<TOption>基础结构,大多数MVC都使用该基础结构设置选项默认值.请参阅 RazorViewEngines >例如.

If you want to be able to resolve services from the container while configuring some options, you need to leverage the IConfigureOptions<TOption> infrastructure, which most of MVC uses to set up the option defaults. See RazorViewEngineOptionsSetup for an example.

首先,将所需的服务添加到集合中:

First, add the services you need to the collection:

services.AddSingleton<IDependency1, Dependency1>();
services.AddSingleton<IDependency2, Dependency2>();

然后,实现安装程序类:

Then, implement the setup class:

public class CustomFileProviderRazorViewEngineOptionsSetup : ConfigureOptions<RazorViewEngineOptions>
{
    public CustomFileProviderRazorViewEngineOptionsSetup(IServiceProvider serviceProvider)
        : base(options => ConfigureRazor(options, serviceProvider))
    {
    }

    private static void ConfigureRazor(RazorViewEngineOptions options, IServiceProvider serviceProvider)
    {
        // Alternative 1 - Resolve each service and new up the instance.
        var dependency1 = serviceProvider.GetService<IDependency1>();
        var dependency2 = serviceProvider.GetService<IDependency2>();

        options.FileProviders.Add(new CustomFileProvider(dependency1, dependency2));

        // Alternative 2 - Same as alternative 1, but with moar magic ;)
        options.FileProviders.Add(ActivatorUtilities.CreateInstance<CustomFileProvider>(serviceProvider));

        // Alternative 3 - Just resolve CustomFileProvider from the service provider.
        // This requires it to be registered first, of course.
        options.FileProviders.Add(serviceProvider.GetService<CustomFileProvider>());
    }
}

这是从容器中解决的,因此它允许您注入IServiceProvider,它可以再次用于解决所需的服务.您可以选择将CustomFileProvider添加到容器中,然后直接解决该问题,就像在替代方法3中一样.

This is resolved from the container, so it'll allow you to inject an IServiceProvider, which can again be used to resolve the services you need. You could optionally add the CustomFileProvider to the container and resolve that directly instead, like in alternative 3.

最后,将安装程序类添加到服务集合:

Finally, add the setup class to the service collection:

services.TryAddEnumerable(
    ServiceDescriptor.Transient<
        IConfigureOptions<RazorViewEngineOptions>,
        CustomFileProviderRazorViewEngineOptionsSetup>());

这会将设置添加到选项构建器管道,这意味着它将与IConfigureOptions<RazorViewEngineOptions>的其他已注册实例一起运行以设置选项对象.

This will add the setup to the options builder pipeline, which means it'll run with the other registered instances of IConfigureOptions<RazorViewEngineOptions> to setup the options object.

这篇关于ConfigureServices中的请求实例的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!