如何将Ninject集成到ASP.NET Core 2.0 Web应用程序中?

前端之家收集整理的这篇文章主要介绍了如何将Ninject集成到ASP.NET Core 2.0 Web应用程序中?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我发现Ninject最近有 introduced support for .NET Standard 2.0 / .NET Core 2.0.

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

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

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

  1. public static void Start()
  2. {
  3. DynamicModuleUtility.RegisterModule(typeof(OnePerRequestHttpModule));
  4. DynamicModuleUtility.RegisterModule(typeof(NinjectHttpModule));
  5. Bootstrapper.Initialize(CreateKernel);
  6. }

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

解决方法

简短回答:

检查this project.但是,它依赖于仍然处于测试版的Ninject 4.0.0,它似乎远不是最终版本(source).对于Ninject 3.3.x,请看下面.

答案很长:

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

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

1)在项目中包含AspNetCoreExtensions.csAspNetCoreMvcExtensions.cs.

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

  1. public class TestService : ITestService
  2. {
  3. public int Data { get; private set; }
  4.  
  5. public TestService()
  6. {
  7. Data = 42;
  8. }
  9. }
  10.  
  11. public interface ITestService
  12. {
  13. int Data { get; }
  14. }

Ninject 3.3.x

如下所示更改Startup.cs:

1)添加这些成员

  1. private readonly AsyncLocal<Scope> scopeProvider = new AsyncLocal<Scope>();
  2. private IKernel Kernel { get; set; }
  3.  
  4. private object Resolve(Type type) => Kernel.Get(type);
  5. private object RequestScope(IContext context) => scopeProvider.Value;

2)添加到ConfigureServices(IServiceCollection服务)(最后)

  1. services.AddSingleton<IHttpContextAccessor,HttpContextAccessor>();
  2.  
  3. services.AddRequestScopingMiddleware(() => scopeProvider.Value = new Scope());
  4. services.AddCustomControllerActivation(Resolve);
  5. services.AddCustomViewComponentActivation(Resolve);

3)添加到配置(IApplicationBuilder应用程序,IHostingEnvironment环境,ILoggerFactory loggerFactory)(开头)

  1. Kernel = RegisterApplicationComponents(app,loggerFactory);

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

  1. private IKernel RegisterApplicationComponents(IApplicationBuilder app,ILoggerFactory loggerFactory)
  2. {
  3. // IKernelConfiguration config = new KernelConfiguration();
  4. Kernel = new StandardKernel();
  5.  
  6. // Register application services
  7. foreach (var ctrlType in app.GetControllerTypes())
  8. {
  9. Kernel.Bind(ctrlType).ToSelf().InScope(RequestScope);
  10. }
  11.  
  12. Kernel.Bind<ITestService>().To<TestService>().InScope(RequestScope);
  13.  
  14. // Cross-wire required framework services
  15. Kernel.BindToMethod(app.GetRequestService<IViewBufferScope>);
  16. Kernel.Bind<ILoggerFactory>().ToConstant(loggerFactory);
  17.  
  18. return Kernel;
  19. }
  20.  
  21. private sealed class Scope : DisposableObject { }

5)创建BindToMethod扩展方法

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

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

Ninject 4.0.0

在版本4中不推荐使用IKernel,因此应该使用IReadOnlyKernel和IKernelConfiguration类(尽管上面的代码应该可以工作).

1)使用新类(IReadOnlyKernel)

  1. private readonly AsyncLocal<Scope> scopeProvider = new AsyncLocal<Scope>();
  2. private IReadOnlyKernel Kernel { get; set; }
  3.  
  4. private object Resolve(Type type) => Kernel.Get(type);
  5. private object RequestScope(IContext context) => scopeProvider.Value;

2)3)是一样的

4)方法略有不同:

  1. private IReadOnlyKernel RegisterApplicationComponents(IApplicationBuilder app,ILoggerFactory loggerFactory)
  2. {
  3. IKernelConfiguration config = new KernelConfiguration();
  4.  
  5. // Register application services
  6. foreach (var ctrlType in app.GetControllerTypes())
  7. {
  8. config.Bind(ctrlType).ToSelf().InScope(RequestScope);
  9. }
  10.  
  11. config.Bind<ITestService>().To<TestService>().InScope(RequestScope);
  12.  
  13. // Cross-wire required framework services
  14. config.BindToMethod(app.GetRequestService<IViewBufferScope>);
  15. config.Bind<ILoggerFactory>().ToConstant(loggerFactory);
  16.  
  17. return config.BuildReadonlyKernel();
  18. }

5)扩展必须使用IKernelConfiguration

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

猜你在找的.NET Core相关文章