简单注入器注入 PageModel ASP.NET Core Razor 页面

Posted

技术标签:

【中文标题】简单注入器注入 PageModel ASP.NET Core Razor 页面【英文标题】:Simple Injector Inject into PageModel ASP.NET Core Razor Pages 【发布时间】:2018-10-08 11:13:44 【问题描述】:

Simple Injector (SI) 文档here 展示了如何将 SI 与 ASP.NET Core 集成:

private void IntegrateSimpleInjector(IServiceCollection services) 
    container.Options.DefaultScopedLifestyle = new AsyncScopedLifestyle();

    services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();

    services.AddSingleton<IControllerActivator>(
        new SimpleInjectorControllerActivator(container));
    services.AddSingleton<IViewComponentActivator>(
        new SimpleInjectorViewComponentActivator(container));

    services.EnableSimpleInjectorCrossWiring(container);
    services.UseSimpleInjectorAspNetRequestScoping(container);

此示例代码展示了如何将 SI 与控制器和视图组件(MVC 模型)集成在一起,我们在 Razor 页面.

但是,这并没有将 SI 集成到 Razor Pages 中,这是随 ASP.NET Core 2.0 发布的新功能。这基本上是一个 MVVM 模型(不完全是)。

所以 Razor 页面的每个视图都有一个PageModel,它就像控制器一样。我想使用 SI 注入到这个类的构造函数中。

【问题讨论】:

【参考方案1】:

我想出了一种使用 Simple Injector 注入 PageModel 构造函数的方法:

public class SimpleInjectorPageModelActivatorProvider : IPageModelActivatorProvider

    private Container Container  get; 
    public SimpleInjectorPageModelActivatorProvider(Container c) => Container = c;
    public Func<PageContext, object> CreateActivator(CompiledPageActionDescriptor d) =>
        _ => Container.GetInstance(d.ModelTypeInfo.AsType());
    public Action<PageContext, object> CreateReleaser(CompiledPageActionDescriptor d) =>
        null;

然后,只需添加这个新的单例注册:

private void IntegrateSimpleInjector(IServiceCollection services)

    container.Options.DefaultScopedLifestyle = new AsyncScopedLifestyle();

    services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();

    services.AddSingleton<IControllerActivator>(
        new SimpleInjectorControllerActivator(container));
    services.AddSingleton<IViewComponentActivator>(
        new SimpleInjectorViewComponentActivator(container));

    // Enables Injection into PageModel
    services.AddSingleton<IPageModelActivatorProvider>(
            new SimpleInjectorPageModelActivatorProvider(container));

    services.EnableSimpleInjectorCrossWiring(container);
    services.UseSimpleInjectorAspNetRequestScoping(container);

它的作用基本上是在创建 PageModel 时调用 Container.GetInstance(instanceType)

【讨论】:

【参考方案2】:

Simple Injector 提供了一种通过扩展方法 AddPageModelActivation 实现此目的的简单方法。

services.AddSimpleInjector(container, options =>

    // AddAspNetCore() wraps web requests in a Simple Injector scope.
    options.AddAspNetCore()
        // Ensure activation of a specific framework type to be created by
        // Simple Injector instead of the built-in configuration system.
        .AddControllerActivation()
        .AddViewComponentActivation()
        .AddPageModelActivation()
        .AddTagHelperActivation();
);

查看整个示例https://simpleinjector.readthedocs.io/en/latest/aspnetintegration.html

【讨论】:

以上是关于简单注入器注入 PageModel ASP.NET Core Razor 页面的主要内容,如果未能解决你的问题,请参考以下文章

反 Sql 注入库 C# Asp.NET

ASP.NET 在嵌套在更新面板中的用户控件中注入 javascript

理解ASP.NET Core

ASP.NET如何防止SQL注入

ASP.NET Core 依赖注入基本用法

ASP.NET Core 依赖注入(DI)