2016-12-28 75 views
1

在ASP.NET MVC应用程序中使用Ninject时,内核是否在您的网站上的并发用户之间共享内核?是否有可能创建一个条件结合,使不同的用户得到的同一界面像这样不同的具体实现......Ninject在ASP.NET MVC和一般网页上

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

没有冲突产生的?

回答

2

是您的网站上的并发用户共享的内核?

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

是否有可能创建一个条件结合,使不同的用户得到的同一界面像这样不同的具体实现......

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

它产生歧义,有额外的责任构成根复杂化,并使其非常难以验证DI配置的正确性。

相反,建议是:

让运行时数据流通过构造的对象图的方法调用。

您可以通过引入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")代码,直到执行后,对象图施工,直到时刻,运行时数据可用。

+0

优秀的答案。非常感谢您的帮助。 –