7

In my NinjectConfigurator I have

container.Bind<IClock>().To<SystemClock>(); 

I have also tried

container.Bind<IClock>().To<SystemClock>().InSingletonScope();

But I get this error:

Error activating IClock using binding from IClock to SystemClock No constructor was available to create an instance of the implementation type.

Activation path: 3) Injection of dependency IClock into parameter clock of constructor of type SystemManager 2) Injection of dependency ISystemManager into parameter systemManager of constructor of type AccountController 1) Request for AccountController

Suggestions: 1) Ensure that the implementation type has a public constructor. 2) If you have implemented the Singleton pattern, use a binding with InSingletonScope() instead.

This is my class with the injection, same as all other working classes with IoC in my project:

private readonly IDateTime _dateTime;
private readonly IClock _clock;

public SystemManager(IDateTime dateTime, IClock clock)
{
    this._dateTime = dateTime;
    this._clock = clock;
}

I couldn't find anything to help me on this. Any help is much appreciated.

Steven
  • 166,672
  • 24
  • 332
  • 435

1 Answers1

12

I haven't used NInject myself for a while, but I believe you want to use ToConstant() to bind to the instance of SystemClock:

container.Bind<IClock>().ToConstant(SystemClock.Instance);
Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • you are a legend. Thanks so much! – Brad Jeffery Nov 11 '15 at 23:09
  • Can you explain why you think ninject is *meant* to handle singleton classes in that way? Were you expecting it to use reflection to look for a static `Instance` member? It's probably because of the following line in the exception message, right?: `2) If you have implemented the Singleton pattern, use a binding with InSingletonScope() instead.` I think that message is misleading, it's probably related to the contextual features, which can mean that under some circumstances contextual information is available to create the instance and under other circumstances it's not. – BatteryBackupUnit Nov 13 '15 at 06:09
  • 1
    @BatteryBackupUnit: Well, that led me to the following documentation: https://github.com/ninject/ninject/wiki/Object-Scopes - that gives an example singleton class, and then appears to provide a binding using `InSingletonScope`. Now it's possible that it was really trying to give that as an *alternative* to implementing the singleton pattern, but if so it's really unclear documentation :( – Jon Skeet Nov 13 '15 at 06:41
  • i agree it's unclear. It should show not only the "before" code but also the "after" code. Which is the same as "before" but without the `public static readonly Shogun Instance = new Shogun();`. Meaning, it still requires a publicly accessible ctor (which is what's missing from `SystemClock` and which leads to the asker's exception - your solution being the appropriate one to fix it). – BatteryBackupUnit Nov 13 '15 at 10:20
  • @BatteryBackupUnit: Righto - will remove that last part from the answer. – Jon Skeet Nov 13 '15 at 11:43
  • 14
    and for those who stumble on this Q&A but are looking for a Microsoft dependency injection answer (ServiceProvider, ServiceCollection...), you can use the similar code : `services.AddSingleton(SystemClock.Instance);` – Pac0 Sep 28 '18 at 11:17
  • 1
    And if you are using Autofac, you can use : `builder.Register(_ => SystemClock.Instance).As().SingleInstance();` (with `builder` as `ContainerBuilder`) – Pac0 Nov 09 '18 at 15:07