aas*_*uki 9 c# entity-framework ninject asp.net-web-api owin
我们正在尝试使用WebAPI管道在Owin中使用Ninject.我们根据此文档设置了所有内容,但我们无法使InRequestScope()工作.
这是startup.cs的重要部分
public class Startup
{
public void Configuration(IAppBuilder app)
{
HttpConfiguration config = new HttpConfiguration();
// Web API routes
config.MapHttpAttributeRoutes();
// Ninject Setup
app.UseNinjectMiddleware(NinjectConfig.CreateKernel);
app.UseNinjectWebApi(config);
}
Run Code Online (Sandbox Code Playgroud)
}
NinjectConfig看起来像这样:
public sealed class NinjectConfig
{
public static IKernel CreateKernel()
{
var kernel = new StandardKernel();
INinjectModule[] modules =
{
new ApplicationModule()
};
instance.Load(modules);
// Do we still need to do this wtih Owin?
instance.Bind<IHttpModule>().To<OnePerRequestHttpModule>();
}
}
Run Code Online (Sandbox Code Playgroud)
我们的ApplicationModule位于一个单独的基础架构项目中,可以访问我们所有不同的层,用于处理DI和映射:
public class ApplicationModule: NinjectModule
{
public override void Load()
{
// IUnitOfWork / EF Setups
Bind<ApplicationContext>().ToSelf().InRequestScope();
Bind<IUnitOfWork>().ToMethod(ctx => ctx.Kernel.Get<ApplicationContext>()});
Bind<ApplicationContext>().ToMethod(ctx => ctx.Kernel.Get<ChromLimsContext>()}).WhenInjectedInto<IDal>();
// other bindings for dals and business objects, etc.
}
}
Run Code Online (Sandbox Code Playgroud)
然后我们有几个接口:
public interface IUnitOfWork()
{
void SaveChanges();
Task SaveChangesAsync();
}
Run Code Online (Sandbox Code Playgroud)
和
public interface IDal()
{
// Crud operations, Sync and Async
}
Run Code Online (Sandbox Code Playgroud)
那么我们的实际课程使用这些:
public class SomeBusinessObject
{
private IUnitOfWork _uow;
private IDal _someDal;
public SomeBusinessObject(IUnitOfWork uow, IDal someDal)
{
_uow = uow;
_someDal = someDal;
}
public Task<SomeResult> SaveSomething(Something something)
{
_someDal.Save(something);
_uow.SaveChanges();
}
}
Run Code Online (Sandbox Code Playgroud)
一些达尔
public class SomeDal : IDal {
private ApplicationContext _applicationContext;
public SomeDal(ApplicationContext applicationContext)
{
_applicationContext = applicationContext;
}
public void Save(Something something)
{
_applicationContext.Somethings.Add(something);
}
}
Run Code Online (Sandbox Code Playgroud)
我们的EF DbContext
public class ApplicationContext : DbContext, IUnitOfWork
{
// EF DBSet Definitions
public void SaveChanges()
{
base.SaveChanges();
}
}
Run Code Online (Sandbox Code Playgroud)
期望是对于每个请求,创建单个ApplicationContext实例并将其作为IUnitOfWork实现注入业务对象,并作为ApplicationContext注入IDals.
相反,正在发生的是为每个使用它的类创建一个新的ApplicationContext实例.如果我将范围从InRequestScope切换到InSingletonScope,那么(正如预期的那样)将为整个应用程序创建1个实例,并将其正确注入到指定的类中.由于这有效,我假设这不是一个绑定问题,而是InRequestScope扩展的问题.
我能找到的唯一一个类似于我遇到的问题就是这个问题,但遗憾的是解决方案无效.我已经引用了他在WebApi和Infrastructure项目中指定的所有软件包,我仔细检查以确保它们被复制到构建目录中.
我究竟做错了什么?
编辑: 一些其他信息.看着这两个Ninject.Web.WebApi.OwinHost和Ninject.Web.Common.OwinHost的Ninject源代码,看来该Owin中间件添加OwinWebApiRequestScopeProvider作为IWebApiRequestScopeProvider.然后,在InRequestScope()扩展方法中使用此提供程序返回名为"Ninject_WebApiScope"的命名范围.这将一直存在,直到被注入交换机的目标类.然后,命名的范围将消失,并创建一个新范围.我想这可能是@BatteryBackupUnit在评论中提到的内容,但我不知道如何纠正它.
这个帖子与这个问题有关...
https://github.com/ninject/Ninject.Web.WebApi/issues/17
我发现InRequestScope的行为似乎会根据你注入它们的方式而改变.例如...
public ValuesController(IValuesProvider valuesProvider1, IValuesProvider valuesProvider2)
{
this.valuesProvider1 = valuesProvider1;
this.valuesProvider2 = valuesProvider2;
}
Run Code Online (Sandbox Code Playgroud)
Ninject将创建并注入相同的IValuesProvider实例.但是如果方法写成......
/// <summary>
/// Initializes a new instance of the <see cref="ValuesController"/> class.
/// </summary>
/// <param name="valuesProvider">The values provider.</param>
public Values2Controller(IKernel kernel)
{
this.valuesProvider1 = kernel.Get<IValuesProvider>();
this.valuesProvider2 = kernel.Get<IValuesProvider>();
}
Run Code Online (Sandbox Code Playgroud)
...这将创建两个新实例.
| 归档时间: |
|
| 查看次数: |
2488 次 |
| 最近记录: |