Ada*_*ger 5 c# dependency-injection ninject inversion-of-control
我正在使用Ninject来实例化一些带有构造函数arg的对象,例如:
class MyClass
{
public MyClass(string myArg)
{
this.myArg = myArg;
}
}
Run Code Online (Sandbox Code Playgroud)
我需要这个类的实例数量直到运行时才会知道,但我想要做的是确保myArg结果在不同的单例实例中的每个变体(因此请求相同的值两次返回相同的实例,但不同args返回不同的实例).
有没有人知道一个好的,最好是内置的方式这样做?
我找到了一篇为Ninject的旧版本编写的文章如何确保每个激活参数变化的一个实例,但希望有更新版本的更整洁的解决方案.
编辑
以下是我使用的内容,改编自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();
}
Run Code Online (Sandbox Code Playgroud)
您可以通过使用绑定IBindingNamedWithOrOnSyntax<T> InScope(Func<IContext, object> scope)方法提供自定义范围来实现所需的行为MyClass
指示只要提供的回调返回的对象保持活动状态 (即尚未被垃圾回收),就应该重新使用通过绑定激活的实例。
因此,您需要返回第一个构造函数参数的值Func<IContext, object> scope,并确保垃圾收集器不会收集它。
这是一个片段:
public class Module : NinjectModule
{
// stores string myArg to protect from CG
ConcurrentBag<string> ParamSet = new ConcurrentBag<string>();
public override void Load()
{
Bind<MyClass>()
.ToSelf()
// custom scope
.InScope((context) =>
{
// get first constructor argument
var param = context.Parameters.First().GetValue(context, context.Request.Target) as string;
// retrieves system reference to string
param = string.Intern(param);
// protect value from CG
if(param != null && ParamSet.Contains(param))
{
// protect from GC
ParamSet.Add(param);
}
// make Ninject to return same instance for this argument
return param;
});
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
796 次 |
| 最近记录: |