【问题标题】:Ninject request scope and callbackNinject 请求范围和回调
【发布时间】: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


    【解决方案1】:

    不确定你是否还需要这个...但你可以将 dbcontext 绑定到 self ,然后在你想使用它时请求它。

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

    虽然应用程序中的连接字符串称为“DefautConnection”,但您需要使用“context”,因为它是在构造函数参数中调用的方式。我是从here得到这个的

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-11-13
      • 1970-01-01
      • 1970-01-01
      • 2011-09-22
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多