1

Using ninject, I have a binding like this:

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

What I want to be able to do is determine whether or not IFoo was constructed without actually trying to use it (since that would cause it to be constructed). Is there a simple way to do that?

Matt Burland
  • 44,552
  • 18
  • 99
  • 171
  • you can try [this mildly hilarious answer from Jon Skeet](http://stackoverflow.com/questions/11162652/c-sharp-get-property-value-without-creating-instance) – Jonesopolis Jun 05 '15 at 15:06
  • 1
    @Jonesy: That's not quite the same thing. I want the kernel to tell me if it constructed an instance of `IFoo`. That's not trying to access an instance member without an instance. – Matt Burland Jun 05 '15 at 15:09
  • Why is it important for you to check whether the instance is created or not? – Steven Jun 05 '15 at 16:15

5 Answers5

3

I think this is a matter of applying the right patterns, such as the proxy pattern:

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();
    }
}

Here we created a LazyFooProxy proxy class that is able to delay the creation of IFoo and it also allows checking whether the foo has been created (by calling the Lazy<T>.IsValueCreated property).

Now you can make the following registration:

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

Now you can use the LazyFooProxy.IsCreated property to check whether MyFoo was created or not.

Steven
  • 166,672
  • 24
  • 332
  • 435
2

It's possible, if you poke around through Ninject's internals enough, that you could find a way to look for the existence of objects that would only be there after this binding has been invoked. But it's easier to just set up your binding to a factory method that sets a flag you can check.

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

You can add OnActivation(...) - which takes an Action as parameter - to the binding. With this you can do whatever you want, including setting a flag to true.

For example:

static bool fooWasCreated = false;

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

there's also an overload available where you get access to IContext. Also it's not necessary to use a static variable, as an alternative you can also access another component which was bound InSingletonScope()

BatteryBackupUnit
  • 12,934
  • 1
  • 42
  • 68
  • I like this answer because I can still defer to ninject to figure out what other dependencies `MyFoo` might need injected. – Matt Burland Jun 06 '15 at 18:56
0

When constructed have it trigger a Boolean that you can check for true/false and just get that value

Vermonster
  • 68
  • 10
  • That is possible *in this case*, but seems a little janky. I'm hoping for a solution that doesn't rely on the specifics of *how* the object was constructed. If `IFoo` was bound to some other implementation, I'd like to still be able to detect that an instance of `IFoo` was constructed. – Matt Burland Jun 05 '15 at 15:07
0

Generally

This may seem to be offtopic but you may find several useful implementations of singleton, by Jon Skeet here.

Question

If I understood it correctly you simply need to add a bool Property indicating whether the instance has been created or not. eg:

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

How ever this is beeing used, it should be made threadsave..

Implementing a Wrapper

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
    }
}

Make sure the only way accessing your IFoo Instance is with FooWrapper.GetInstance()

Community
  • 1
  • 1
LuckyLikey
  • 3,504
  • 1
  • 31
  • 54
  • As per my comment to @Vermonster's answer, this kind of solution requires knowing something about the implementation of `IFoo`. I'm looking for a solution that would work regardless of the implementation of `IFoo`. – Matt Burland Jun 05 '15 at 15:40
  • @matt burland either the Interface implements this property or you need to wrap the whole interface in a new singleton class. Ensure all your classes access this class. This might work. – LuckyLikey Jun 05 '15 at 15:50
  • An interface can't have a static property. – Matt Burland Jun 05 '15 at 16:36
  • Whups... sorry named it wrong.. its not an interface – LuckyLikey Jun 05 '15 at 17:05