我們試圖在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