我正在使用Ninject来实例化一些带有构造函数arg的对象,例如:
class MyClass
{
public MyClass(string myArg)
{
this.myArg = myArg;
}
}
我需要这个类的实例数量直到运行时才知道,但我想要做的是确保myArg
的每个变体都会产生不同的单例实例(所以要求相同的值两次返回相同的实例,但不同的args返回不同的实例。)
有没有人知道一种好的,最好是内置的方式呢?
我发现了一篇为Ninject How To Ensure One Instance per Variation of Activation Parameters旧版本编写的文章,但希望有更新版本的更整洁的解决方案。
修改
以下是我使用的内容,改编自Akim的答案:
private readonly ConcurrentBag<string> scopeParameters = new ConcurrentBag<string>();
internal object ParameterScope(IContext context, string parameterName)
{
var param = context.Parameters.First(p => p.Name.Equals(parameterName));
var paramValue = param.GetValue(context, context.Request.Target) as string;
paramValue = string.Intern(paramValue);
if (paramValue != null && !scopeParameters.Contains(paramValue))
{
scopeParameters.Add(paramValue);
}
return paramValue;
}
public override void Load()
{
Bind<MyClass>()
.ToSelf()
.InScope(c => ParameterScope(c, "myArg"));
Bind<IMyClassFactory>()
.ToFactory();
}
答案 0 :(得分:3)
您可以使用IBindingNamedWithOrOnSyntax<T> InScope(Func<IContext, object> scope)
绑定<{1}}方法为自定义作用域提供自定义作用域
表示通过绑定激活的实例应重新使用 只要提供的回调返回的对象保持活动 (也就是说,没有被垃圾收集)。
因此,您需要从MyClass
返回第一个构造函数参数的值,并确保garbage-collector不会收集它。
这是一个片段:
Func<IContext, object> scope