c# – Ninject Memoize Singleton Scope中的实例
我正在使用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(); } 解决方法
您可以通过使用IBindingNamedWithOrOnSyntax< T>提供自定义范围来实现需求行为.用于MyClass绑定的InScope(Func< IContext,object> scope)方法
因此,您需要从Func< IContext,object>返回第一个构造函数参数的值. scope并确保garbage-collector不会收集它. 这是一个片段: 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; }); } } ps:full sample code with unittests (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |