【发布时间】:2015-02-05 09:26:26
【问题描述】:
我在使用 Owin 的 MVC 项目中遇到了 Ninject 问题。
我有一个不特定于我的项目的 UnitOfWork 通用类:
public class UnitOfWork : IUnitOfWork
{
public UnitOfWork(DbContext context)
{...}
}
我使用自定义 DbContext 定义了两个存储库:
public UserRepository : IUserRepository
{
public UserRepository(MyEntities context)
{...}
}
public OrderRepository : IOrderRepository
{
public OrderRepository(MyEntities context)
{...}
}
然后我有一个使用工作单元和存储库的 ApiController。
public OrderController : ApiController
{
public OrderController(IUnitOfWork uow, IUserRepository userRepository, IOrderRepository orderRepository)
{...}
}
我在一个模块中配置我的 Ninject 内核。我的绑定具有请求范围。
public class MyModule : Ninject.Modules.NinjectModule
{
public override void Load()
{
// Bind all the repositories
this.Bind(x =>
x.FromAssembliesMatching("*.Repositories")
.SelectAllClasses()
.BindDefaultInterface()
.Configure(c => c.InRequestScope()));
// Bind the DbContext of the application
this.Bind<MyEntities>()
.ToSelf()
.InRequestScope();
// To bind the UnitOfWork, I need to specify the real DbContext to use. For that I use a callback which provide argument to constructor :
this.Bind<IUnitOfWork>()
.To<UnitOfWork>()
.InRequestScope()
.WithConstructorArgument("context", GetContext);
}
private Object GetContext(IContext context, ITarget target)
{
IResolutionRoot resolver;
ActivationBlock scope;
scope = context.Request.GetScope() as ActivationBlock;
resolver = scope ?? (IResolutionRoot)context.Kernel;
var o = resolver.Get<MyEntities>();
var o2 = resolver.Get<MyEntities>();
var same = Object.ReferenceEquals(o, o2);
return o;
}
}
然后我在 Startup 类中像这样使用 Owin 激活 Ninject:
public class Startup
{
public void Configuration(IAppBuilder app)
{
...
app.UseNinjectMiddleware(Startup.CreateKernel);
var config = new HttpConfiguration();
...
app.UseNinjectWebApi(config);
}
private static IKernel CreateKernel()
{
var kernel = new StandardKernel();
kernel.Load(new MyModule());
return kernel;
}
}
看起来不错,但有一个大问题。存储库共享相同的 DbContext,但 UnitOfWork 中的 DbContext 是不同的实例。 在函数 GetContext 中,范围始终为空,因此从内核中检索 MyContext 实例。布尔变量 same 始终为 false。问题就在这里。内核的 Get 函数返回一个新的实例,而不是请求范围的实例。
【问题讨论】:
标签: ninject