检查是否创建了一个懒惰的单例

时间:2015-06-05 14:52:02

标签: c# ninject

使用ninject,我有这样的绑定:

kernel.Bind<IFoo>().To<MyFoo>().InSingletonScope()
    .WithConstructorArgument("bar", new Action<IFoo>(foo =>
    {
        // some function here
    }));

我希望能够做的是确定IFoo是否在没有实际尝试使用的情况下构建(因为这将导致它被构造)。有没有一种简单的方法可以做到这一点?

5 个答案:

答案 0 :(得分:3)

我认为这是应用正确模式的问题,例如代理模式:

public class LazyFooProxy : IFoo
{
    private readonly Lazy<IFoo> foo;
    public LazyFooProxy(Lazy<IFoo> foo) {
        this.foo = foo;
    }

    public bool IsCreated {
        get { return this.foo.IsValueCreated; }
    }

    void IFoo.Method() {
        this.foo.Value.Method();
    }
}

这里我们创建了一个LazyFooProxy代理类,它能够延迟IFoo的创建,并且还允许检查是否已经创建了foo(通过调用Lazy<T>.IsValueCreated属性)。

现在您可以进行以下注册:

var lazyFoo = new LazyFooProxy(new Lazy<IFoo>(kernel.Get<MyFoo>));
kernel.Bind<IFoo>().ToInstance(lazyFoo);
kernel.Bind<MyFoo>().InSingletonScope();

现在,您可以使用LazyFooProxy.IsCreated属性检查是否已创建MyFoo

答案 1 :(得分:2)

如果你足够了解Ninject的内部结构,你可以找到一种方法来寻找只有在调用此绑定后才存在的对象。但是,将绑定设置为设置可以检查的标志的工厂方法会更容易。

kernel.Bind<IFoo>().ToMethod(
    kernel => {
        Tracker.FooIsInitialized = true;
        return new MyFoo(kernel.Get<IDependency>());
    })
    .InSingletonScope()
    .WithConstructorArgument("bar", new Action<IFoo>(foo =>
    {
        // some function here
    }));

答案 2 :(得分:2)

您可以将OnActivation(...) - 以Action作为参数 - 添加到绑定中。有了它,你可以做任何你想做的事情,包括将标志设置为true。

例如:

static bool fooWasCreated = false;

kernel.Bind<IFoo>().To<MyFoo>()
      .InSingletonScope()
      .OnActivation(fooInstance => fooWasCreated = true);

还有一个过载,您可以访问IContext。此外,没有必要使用静态变量,作为替代方案,您还可以访问绑定的另一个组件InSingletonScope()

答案 3 :(得分:0)

构造时,它会触发一个布尔值,您可以检查是否为真/假,并获得该值

答案 4 :(得分:0)

一般

这可能看起来像是非正式的,但你可能会发现Jon Skeet here有几个有用的单身实现。

问题

如果我理解正确,您只需添加一个bool属性,指示实例是否已创建。例如:

public static bool IsCreated { get { return _instance != null; } }

如何使用它,它应该成为线程...

实施包装

public static class FooWrapper 
{
    public static bool IsCreated { get; private set; } // default false

    public static IFoo GetInstance()
    {
        IsCreated = true;

        // return the Singleton Instance of IFoo
    }
}

确保访问IFoo实例的唯一方法是使用FooWrapper.GetInstance()