简体   繁体   English

Ninject在ASP.NET MVC和一般的Web中

[英]Ninject in ASP.NET MVC and on the web in general

When using Ninject in an ASP.NET MVC application, is the kernel shared among concurrent users on your website? 在ASP.NET MVC应用程序中使用Ninject时,网站上的并发用户之间是否共享内核? Is it possible to create a conditional binding so that different users get different concrete implementations of the same Interface something like this... 是否可以创建条件绑定,以便不同的用户获得相同接口的不同具体实现,如下所示...

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

without conflict arising? 没有冲突吗?

is the kernel shared among concurrent users on your website? 网站上的并发用户之间共享内核吗?

In a typical (and recommended) setup, you have one instance of the Kernel per AppDomain. 在典型的(建议使用)设置中,每个AppDomain都有一个Kernel实例。 This means that every request (and thus every user) accesses the same Kernel instance (and possibly in parallel). 这意味着每个请求(因此每个用户)都访问相同的Kernel实例(可能并行)。

Is it possible to create a conditional binding so that different users get different concrete implementations of the same Interface something like this... 是否可以创建条件绑定,以便不同的用户获得相同接口的不同具体实现,如下所示...

It is not recommended to base the construction of an object graph based on runtime data (your user == "A" is decision based on runtime data user ). 不建议基于运行时数据构建对象图的基础(您的user == "A"是基于运行时数据user决策)。 This exposes the same downsides as injecting runtime data into application composents does: 这暴露出与将运行时数据注入应用程序组件相同的缺点:

it causes ambiguity, complicates the composition root with an extra responsibility and makes it extraordinarily hard to verify the correctness of your DI configuration. 这会造成歧义,使组成根复杂化,并产生额外的责任,并且使验证DI配置的正确性变得异常困难。

Instead, the advice is to: 相反,建议是:

to let runtime data flow through the method calls of constructed object graphs. 使运行时数据流经构造的对象图的方法调用。

You can achieve this simply and elegantly by introducing a proxy for IFoo that forwards any incoming call to either FooForA or FooForB , based on the runtime data. 通过引入IFoo代理,您可以简单而优雅地实现此目的,该代理根据运行时数据将所有传入呼叫转发到FooForAFooForB For instance: 例如:

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; }
    }
}

Using this FooSelectorProxy , you can make the following registration: 使用此FooSelectorProxy ,您可以进行以下注册:

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

This postpones the execution of the if (user == "A") code until after the construction of the object graph until the moment that runtime data is available. 这会将if (user == "A")代码的执行推迟到对象图构造完成之后 ,直到运行时数据可用为止。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM