问题描述
我发现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.PreApplicationStartMethod
和WebActivatorEx.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?
推荐答案
简短答案:
检查此项目.但是,它依赖于仍处于beta版的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)的有效解决方案.该代码主要来自缺少-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. cs 和 AspNetCoreMvcExtensions. 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
:
Ninject 3.3.x
Change Startup.cs
as indicated below:
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)相同
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
5) The extension must use an 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应用程序中?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!