简体   繁体   中英

Simple Injector Inject into PageModel ASP.NET Core Razor Pages

Simple Injector ( SI ) Documentation here shows how to integrate SI with 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);
}

This example code shows how to integrate SI with Controllers and ViewComponents (The MVC model) that we were used to work with before Razor Pages .

However, this doe not integrate SI into Razor Pages , the new feature released with ASP.NET Core 2.0. This is basically a MVVM model (not exactly).

So Razor pages have one PageModel for each view, and it is like the controller. And I would like to inject into the constructor of this class using SI.

I figured one way to inject into the construtor of PageModel using Simple Injector:

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;
}

And then, just add this new singleton registration:

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);
}

What it does, is basically call Container.GetInstance(instanceType) whenever a PageModel is being created.

Simple Injector offer a simple way to achieve this with the extension method 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();
});

To see the whole example https://simpleinjector.readthedocs.io/en/latest/aspnetintegration.html

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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