我们试图在Owin中使用Ninject和WebAPI管道。我们根据this documentation设置了一切设置,但我们无法使InRequestScope()正常工作。在Owin和InRequestScope中使用Ninject
这里的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);
}
}的显著部分
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>();
}
}
我们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.
}
}
然后我们有几个接口:
public interface IUnitOfWork()
{
void SaveChanges();
Task SaveChangesAsync();
}
和
public interface IDal()
{
// Crud operations, Sync and Async
}
然后我们使用这些实际类:
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();
}
}
有些达尔
public class SomeDal : IDal {
private ApplicationContext _applicationContext;
public SomeDal(ApplicationContext applicationContext)
{
_applicationContext = applicationContext;
}
public void Save(Something something)
{
_applicationContext.Somethings.Add(something);
}
}
我们EF的DbContext
public class ApplicationContext : DbContext, IUnitOfWork
{
// EF DBSet Definitions
public void SaveChanges()
{
base.SaveChanges();
}
}
的期望是,为每个请求,ApplicationContext中的单个实例被创建和注入业务对象作为IUnitOfWork实现进入IDals作为一个ApplicationContext。
取而代之的是,正在为每个使用它的类创建一个ApplicationContext的新实例。如果我将范围从InRequestScope切换到InSingletonScope,那么(如预期的那样)为整个应用程序创建了一个实例,并将其正确注入到指定的类中。既然这样,我假设这不是一个绑定问题,而是一个InRequestScope扩展的问题。
我可以找到类似于我正在经历的唯一问题是this one,但不幸的是该解决方案无法正常工作。我已经引用了他在WebApi和基础结构项目中指定的所有包,并且我进行了双重检查以确保它们被复制到构建目录中。
我在做什么错?
编辑: 一些额外的信息。查看Ninject.Web.WebApi.OwinHost和Ninject.Web.Common.OwinHost中的Ninject源代码,似乎Owin Middleware将OwinWebApiRequestScopeProvider添加为IWebApiRequestScopeProvider。然后,此提供程序将用于InRequestScope()扩展方法中,以返回名为“Ninject_WebApiScope”的命名范围。这将一直存在,直到注入交换机的目标类为止。命名的作用域消失,并创建一个新的作用域。我认为这可能是@BatteryBackupUnit在他们的评论中提到的,但我不知道如何纠正它。
我的猜测是你的第二个'Bind()'引起了这个问题。你没有将它设置为'InRequestScope()' –
LukeP
2014-12-04 21:06:36
不幸的是,没有工作。我也试过只绑定ApplicationContext到自己的InRequestScope,然后只绑定IUnitOfWork ToMethod(ctx => ctx.Kernel.Get())。InRequestScope() –
aasukisuki
2014-12-04 21:18:21
'.InRequestScope() * 捆绑?有一个与ninject nuget软件包安装/升级相关的“已知”问题,它没有正确设置,并且请求范围特定的注入内容未正确注册。 '.InRequestScope()'没有效果 - 遗憾的是甚至没有抛出异常。 – BatteryBackupUnit 2014-12-05 07:15:37