Ninject 在 ASP.NET MVC 和网络上

Ninject in ASP.NET MVC and on the web in general

在 ASP.NET MVC 应用程序中使用 Ninject 时,您网站上的并发用户是否共享内核?是否可以创建条件绑定,以便不同的用户获得同一接口的不同具体实现,例如...

 if (user == "A")
      kernel.Bind<IFoo>().To<FooForA>();
 else
      kernel.Bind<IFoo>().To<FooForB>();

没有发生冲突?

is the kernel shared among concurrent users on your website?

在典型(推荐)设置中,每个 AppDomain 有一个 Kernel 实例。这意味着每个请求(因此每个用户)都访问相同的 Kernel 实例(并且可能是并行的)。

Is it possible to create a conditional binding so that different users get different concrete implementations of the same Interface something like this...

不建议基于运行时数据来构建对象图(您的user == "A" 是基于运行时数据的决定user)。这暴露了与 injecting runtime data into application composents 相同的缺点:

it causes ambiguity, complicates the composition root with an extra responsibility and makes it extraordinarily hard to verify the correctness of your DI configuration.

相反,建议是:

to let runtime data flow through the method calls of constructed object graphs.

您可以通过为 IFoo 引入代理来简单而优雅地实现这一点,该代理根据运行时数据将任何传入呼叫转发给 FooForAFooForB。例如:

public sealed class FooSelectorProxy : IFoo
{
    private readonly FooForA afoo;
    private readonly FooForB bfoo;
    public FooSelectorProxy(FooForA afoo, FooForB bfoo) {
        this.afoo = afoo;
        this.bfoo = bfoo;
    }

    public object FooMethod(object args) {
        return CurrentFoo.FooMethod(args);
    }

    private IFoo CurrentFoo {
        get { return user == "A" ? this.afoo : this.bfoo; }
    }
}

使用此 FooSelectorProxy,您可以进行以下注册:

kernel.Bind<IFoo>().To<FooSelectorProxy>();

这会将 if (user == "A") 代码的执行推迟到 构建对象图之后,直到运行时数据可用。