2014-12-07 5 views
1

У меня проблема с Ninject в проекте MVC с использованием Owin.Область запроса запроса и обратного вызова

У меня есть общий класс для 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, но DbContext в UnitOfWork - это другой экземпляр. В функции GetContext область всегда равна нулю, поэтому экземпляр MyContext извлекается из ядра. Логическая переменная такая же всегда неверна. Проблема здесь. Функция Get из ядра возвращает новый экземпляр вместо экземпляра области запроса.

ответ

0

Не уверен, что вам все еще нужно это ... но вы можете привязать dbcontext к себе, а затем попросить его, когда вы хотите его использовать.

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

Хотя строка подключения в приложении называется «DefautConnection», вам нужно использовать «контекст», потому что это, как это называется в аргумент конструктора. Я получил это от here

Смежные вопросы