Ale*_*xei 11 ninject asp.net-core-2.0
我发现Ninject最近引入了对.NET Standard 2.0/.NET Core 2.0的支持.
但是,我找不到任何实际将其集成到Web应用程序中的扩展(例如类似于Ninject.Web.Common)
从旧的ASP.NET MVC解决方案的代码看,我意识到整个机制是不同的,因为它依赖于经典的机制,WebActivatorEx.PreApplicationStartMethod并且WebActivatorEx.ApplicationShutdownMethodAttribute在ASP.NET Core中不再可用.
此外,旧Ninject.Web.Common程序集提供了几个用于初始化的有用类--Bootstrapper,OnePerRequestHttpModule,NinjectHttpModule:
public static void Start()
{
DynamicModuleUtility.RegisterModule(typeof(OnePerRequestHttpModule));
DynamicModuleUtility.RegisterModule(typeof(NinjectHttpModule));
Bootstrapper.Initialize(CreateKernel);
}
Run Code Online (Sandbox Code Playgroud)
问题:有没有关于如何将Ninject集成到ASP.NET Core 2.0 Web应用程序中的示例?
Ale*_*xei 17
检查这个项目.但是,它依赖于仍处于测试版的Ninject 4.0.0,它似乎远不是最终版本(源代码).对于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.cs和AspNetCoreMvcExtensions.cs.
2)创建一个非常简单的服务来用于测试DI:TestService它实现ITestService:
public class TestService : ITestService
{
public int Data { get; private set; }
public TestService()
{
Data = 42;
}
}
public interface ITestService
{
int Data { get; }
}
Run Code Online (Sandbox Code Playgroud)
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;
Run Code Online (Sandbox Code Playgroud)
2)加入ConfigureServices(IServiceCollection services)(最后)
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
services.AddRequestScopingMiddleware(() => scopeProvider.Value = new Scope());
services.AddCustomControllerActivation(Resolve);
services.AddCustomViewComponentActivation(Resolve);
Run Code Online (Sandbox Code Playgroud)
3)加入Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)(开头)
Kernel = RegisterApplicationComponents(app, loggerFactory);
Run Code Online (Sandbox Code Playgroud)
4)添加以下方法和内部类:
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 { }
Run Code Online (Sandbox Code Playgroud)
5)创建BindToMethod扩展方法
public static class BindingHelpers
{
public static void BindToMethod<T>(this IKernel config, Func<T> method) =>
config.Bind<T>().ToMethod(c => method());
}
Run Code Online (Sandbox Code Playgroud)
6)通过将自定义服务注入控制器,将断点设置为测试服务构造函数并检查调用堆栈来测试DI.除了提供一个实例,调用堆栈应该点击自定义代码来集成Ninject(例如ConfigureRequestScoping方法)
IKernel 已在版本4中弃用,因此应使用IReadOnlyKernel和IKernelConfiguration类(尽管上面的代码应该可用).
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;
Run Code Online (Sandbox Code Playgroud)
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();
}
Run Code Online (Sandbox Code Playgroud)
5)扩展必须使用 IKernelConfiguration
public static class BindingHelpers
{
public static void BindToMethod<T>(
this IKernelConfiguration config, Func<T> method) =>
config.Bind<T>().ToMethod(c => method());
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
5284 次 |
| 最近记录: |