2014-12-07 96 views
1

我在使用Owin的MVC项目中遇到Ninject问题。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; 
    } 
} 

然后我激活Ninject与Owin这样在启动类:

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实例从内核中检索。布尔变量相同始终为false。问题在这里。内核的Get函数返回一个新实例,而不是请求范围的实例。

回答

0

不知道你是否仍然需要这个...但你可以将dbcontext绑定到自己,然后当你想使用它的时候请求它。

 Bind<ApplicationDbContext>().ToSelf(); 
     Bind<IUserStoreGuid<User>>().To<UserStoreGuid<User>>().WithConstructorArgument("context", Kernel.GetService(typeof(ApplicationDbContext))); 

虽然在应用程序的连接字符串被称为“DefautConnection”,你需要使用“上下文”,因为这是它是如何调用构造函数的参数。我从here得到这个