【问题标题】:Ninject InSingletonScope Inject Single Parameter Every RequestNinject InSingletonScope 每次请求都注入单个参数
【发布时间】:2018-05-20 16:27:03
【问题描述】:
我正在使用 Ninject
如果需要,我有一个用于保存和构建一些缓存数据的类。它在我的 Niject 绑定中设置如下
kernel.Bind<IConsistencyCheckCacheHelper>().To<ConsistencyCheckCacheHelper>().InSingletonScope();
类在第一次创建类时注入了一些必需的依赖项,然后每次都注入同一个实例。
但在需要重建数据的情况下,我需要注入运行时依赖项。
我将其用作应用程序范围的缓存,
任何想法如何做到这一点?
【问题讨论】:
标签:
c#
dependency-injection
ninject
ninject.web.mvc
【解决方案1】:
类在第一次创建类时注入了一些必需的依赖项,然后每次都注入同一个实例。
该类已在 Ninject 中注册为单例。这意味着 Ninject 第一次解析 IConsistencyCheckCacheHelper 时会创建一个 ConsistencyCheckCacheHelper 的实例,然后它会一遍又一遍地使用同一个实例。
因此,Ninject 不会一遍又一遍地将相同的依赖实例注入ConsistencyCheckCacheHelper。它只创建了ConsistencyCheckCacheHelper 的一个实例,因此注入其中的任何依赖项实例都不会改变。
如果您希望 ConsistencyCheckCacheHelper 使用的依赖项在每次解析时都更改,那么您不能将其注册为单例。您需要使用不同的范围。
.InTransientScope()(默认值)意味着每次解析一个类型时都会创建一个新实例。
.InRequestScope() 表示为每个 Web 请求创建一个新实例。
它仍然比这复杂一点。例如,如果ConsistencyCheckCacheHelper 注册为瞬态,则每次都会创建一个新实例。但是如果它依赖于其他东西并且 那个 依赖被注册为单例,ConsistencyCheckCacheHelper 的每个新实例都将接收到该依赖的相同单例实例。
通常建议我们从临时依赖项开始。除非我们特别需要重用一个实例,否则创建新对象的成本可能不会那么高。对于 Web 应用程序,InRequestScope 可能是安全的。如果我确定我可以安全地重用该类的一个实例以及一个实例(如果它的依赖项及其依赖项等等),我只会使用单例范围。
Ninject object scopes
【解决方案2】:
这可能不是最好的方法,但它有效,创建 2 个代表同一个类的接口
public interface DepInterfaceOne
{
int MethodWithCachedData();
void InfoRequiredForAtRunTime(object RunTimeObject);
}
public interface DepInterfaceTwo: IConsistencyCheckCacheHelper
{
}
并以这种方式设置您的绑定
kernel.Bind<DepInterfaceOne>().To<DepInterfaceOneClass>().InSingletonScope();
kernel.Bind<DepInterfaceOneTwo>().ToMethod(a =>
{
DepInterfaceOne toReturn = kernel.Get<DepInterfaceOne>();
toReturn.InfoRequiredForAtRunTime(HttpContext.Current.Session["InfoRequired"]);
return toReturn;
});