如何将 Ninject 集成到 ASP.NET Core 2.0 Web 应用程序中? [英] How to integrate Ninject into ASP.NET Core 2.0 Web applications?

查看:27
本文介绍了如何将 Ninject 集成到 ASP.NET Core 2.0 Web 应用程序中?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我发现 Ninject 最近引入了对 .NET Standard 2.0/.NET 的支持核心 2.0.

I have found out that Ninject has recently introduced support for .NET Standard 2.0 / .NET Core 2.0.

但是,我找不到任何扩展来实际将其集成到 Web 应用程序中(例如类似于 Ninject.Web.Common)

However, I cannot find any extension to actually integrate it in the Web application (e.g similar to Ninject.Web.Common)

查看旧的 ASP.NET MVC 解决方案的代码,我意识到整个机制不同,因为经典的依赖于 WebActivatorEx.PreApplicationStartMethodWebActivatorEx.ApplicationShutdownMethodAttribute 在 ASP.NET Core 中不再可用.

Looking on the code from an old ASP.NET MVC solution, I realized that the whole mechanism is different as the classic one relied on WebActivatorEx.PreApplicationStartMethod and WebActivatorEx.ApplicationShutdownMethodAttribute which are no longer available in ASP.NET Core.

此外,旧的 Ninject.Web.Common 程序集提供了几个用于初始化的有用类 - Bootstrapper、OnePerRequestHttpModule、NinjectHttpModule:

Also, the old Ninject.Web.Common assembly provided several useful classes used for initialization - Bootstrapper, OnePerRequestHttpModule, NinjectHttpModule:

public static void Start()
{
    DynamicModuleUtility.RegisterModule(typeof(OnePerRequestHttpModule));
    DynamicModuleUtility.RegisterModule(typeof(NinjectHttpModule));
    Bootstrapper.Initialize(CreateKernel);
}

问题:有没有关于如何将 Ninject 集成到 ASP.NET Core 2.0 Web 应用程序的示例?

Question: is there any example of how to integrate Ninject into an ASP.NET Core 2.0 Web application?

推荐答案

简答:

检查这个项目.然而,它依赖于仍处于测试版的 Ninject 4.0.0,它似乎离最终版本还很远(来源).对于 Ninject 3.3.x,请看下面.

Short answer:

check this project. However, it relies on Ninject 4.0.0 which is still in beta version and it seems far from a final version (source). For Ninject 3.3.x look below.

感谢 @Steven 我设法创建了 ASP.NET Core 2.0 和 Ninject(3.3.x 和 4.0)的工作解决方案.代码主要来自Missing-Core-DI-Extensions Git 存储库,非常感谢 dotnetjunkie.

Thanks to @Steven I managed to create a working solution of ASP.NET Core 2.0 and Ninject (both 3.3.x and 4.0). The code is mainly from Missing-Core-DI-Extensions Git repo, so great thanks to dotnetjunkie.

无论引用的 Ninject 版本如何,都必须执行以下操作:

The following must be performed regardless of referenced Ninject version:

1) 包括 AspNetCoreExtensions.csAspNetCoreMvcExtensions.cs 在您的项目中.

1) Include AspNetCoreExtensions.cs and AspNetCoreMvcExtensions.cs in your project.

2) 创建一个非常简单的服务来用于测试 DI:TestService 实现了 ITestService:

2) Create a very simple service to use for testing the DI: TestService that implements ITestService:

public class TestService : ITestService
{
    public int Data { get; private set; }

    public TestService()
    {
        Data = 42;
    }
} 

public interface ITestService
{
    int Data { get; }
}

Ninject 3.3.x

更改Startup.cs,如下所示:

1) 添加这些成员

private readonly AsyncLocal<Scope> scopeProvider = new AsyncLocal<Scope>();
private IKernel Kernel { get; set; }

private object Resolve(Type type) => Kernel.Get(type);
private object RequestScope(IContext context) => scopeProvider.Value;  

2) 添加到ConfigureServices(IServiceCollection services)(最后)

services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();

services.AddRequestScopingMiddleware(() => scopeProvider.Value = new Scope());
services.AddCustomControllerActivation(Resolve);
services.AddCustomViewComponentActivation(Resolve);

3) 添加到Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)(开头)

Kernel = RegisterApplicationComponents(app, loggerFactory);

4) 添加如下方法和内部类:

4) Add the following method and inner class:

private IKernel RegisterApplicationComponents(
    IApplicationBuilder app, ILoggerFactory loggerFactory)
{
    // IKernelConfiguration config = new KernelConfiguration();
    Kernel = new StandardKernel();

    // Register application services
    foreach (var ctrlType in app.GetControllerTypes())
    {
        Kernel.Bind(ctrlType).ToSelf().InScope(RequestScope);
    }

    Kernel.Bind<ITestService>().To<TestService>().InScope(RequestScope);

    // Cross-wire required framework services
    Kernel.BindToMethod(app.GetRequestService<IViewBufferScope>);
    Kernel.Bind<ILoggerFactory>().ToConstant(loggerFactory);

    return Kernel;
}

private sealed class Scope : DisposableObject { }

5) 创建BindToMethod 扩展方法

public static class BindingHelpers
{
    public static void BindToMethod<T>(this IKernel config, Func<T> method) => 
        config.Bind<T>().ToMethod(c => method());
}

6) 通过将自定义服务注入控制器、在测试服务构造函数中设置断点并检查调用堆栈来测试 DI.除了提供一个实例,调用栈还应该点击自定义代码来集成 Ninject(例如 ConfigureRequestScoping 方法)

6) Test DI by injecting custom service into a controller, setting a breakpoint into test service constructor and checking the call stack. Besides providing an instance, the call stack should hit custom code to integrate Ninject (e.g. ConfigureRequestScoping method)

IKernel 在第 4 版中已被弃用,因此应使用 IReadOnlyKernel 和 IKernelConfiguration 类(尽管上面的代码应该可以工作).

IKernel has been deprecated in version 4, so IReadOnlyKernel and IKernelConfiguration classes should be used (although above code should work).

1) 使用新类 (IReadOnlyKernel)

private readonly AsyncLocal<Scope> scopeProvider = new AsyncLocal<Scope>();
private IReadOnlyKernel Kernel { get; set; }

private object Resolve(Type type) => Kernel.Get(type);
private object RequestScope(IContext context) => scopeProvider.Value;

2) 3) 是一样的

2) 3) are the same

4) 方法略有不同:

private IReadOnlyKernel RegisterApplicationComponents(
    IApplicationBuilder app, ILoggerFactory loggerFactory)
{
    IKernelConfiguration config = new KernelConfiguration();

    // Register application services
    foreach (var ctrlType in app.GetControllerTypes())
    {
        config.Bind(ctrlType).ToSelf().InScope(RequestScope);
    }

    config.Bind<ITestService>().To<TestService>().InScope(RequestScope);

    // Cross-wire required framework services
    config.BindToMethod(app.GetRequestService<IViewBufferScope>);
    config.Bind<ILoggerFactory>().ToConstant(loggerFactory);

    return config.BuildReadonlyKernel();
}

5) 扩展必须使用 IKernelConfiguration

public static class BindingHelpers
{
    public static void BindToMethod<T>(
        this IKernelConfiguration config, Func<T> method) =>
            config.Bind<T>().ToMethod(c => method());
}

这篇关于如何将 Ninject 集成到 ASP.NET Core 2.0 Web 应用程序中?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆