How do I configure Ninject to inject the NodaTime IClock
Asked Answered
P

1

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.

Pavior answered 11/11, 2015 at 6:27 Comment(0)
B
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);
Baking answered 11/11, 2015 at 6:57 Comment(7)
you are a legend. Thanks so much!Pavior
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.Eurhythmics
@BatteryBackupUnit: Well, that led me to the following documentation: 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 :(Baking
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).Eurhythmics
@BatteryBackupUnit: Righto - will remove that last part from the answer.Baking
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<IClock>(SystemClock.Instance);Bina
And if you are using Autofac, you can use : builder.Register(_ => SystemClock.Instance).As<IClock>().SingleInstance(); (with builder as ContainerBuilder)Bina

© 2022 - 2024 — McMap. All rights reserved.