Ninject在Singleton范围内记忆实例

时间:2013-01-24 13:24:16

标签: c# dependency-injection inversion-of-control ninject

我正在使用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();
}

1 个答案:

答案 0 :(得分:3)

您可以使用IBindingNamedWithOrOnSyntax<T> InScope(Func<IContext, object> scope)绑定<{1}}方法为自定义作用域提供自定义作用域

  

表示通过绑定激活的实例应重新使用   只要提供的回调返回的对象保持活动   (也就是说,没有被垃圾收集)。

因此,您需要从MyClass返回第一个构造函数参数的值,并确保不会收集它。

这是一个片段:

Func<IContext, object> scope

ps:full sample code with unittests