简体   繁体   中英

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? 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. This means that every request (and thus every user) accesses the same Kernel instance (and possibly in parallel).

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 ). 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.

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. 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:

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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