Ninject - Injecting singleton - ninject

I have this error when clicking a link on a site I'm creating
Error activating IEntityCache using binding from IEntityCache to EntityCache
No constructor was available to create an instance of the implementation type.
Activation path:
4) Injection of dependency IEntityCache into parameter entityCache of constructor of type AlbumRepository
3) Injection of dependency IAlbumRepository into parameter albumRepository of constructor of type AlbumService
2) Injection of dependency IAlbumService into parameter albumService of constructor of type AlbumController
1) Request for AlbumController
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.
EntityCache is a singleton with no public construction. So this is how I've done my Ninject bindings
kernel.Bind<IAlbumService>().To<AlbumService>();
kernel.Bind<IAlbumRepository>().To<AlbumRepository>();
kernel.Bind<IDbSetWrapper<Album>>().To<DbSetWrapper<Album>>();
kernel.Bind<IEntityCache>().To<EntityCache>().InSingletonScope();
What am I doing wrong?
EDIT
Here's my repository:
public AlbumRepository(DatabaseContext context, IDbSetWrapper<Album> dbSetWrapper, IEntityCache entityCache)
: base(context, dbSetWrapper, entityCache)
How do I pass in an IEntityCache?

EntityCache is a singleton with no public construction.
And how do you expect your DI framework to be able to instantiate this class? This cannot possibly work if your class doesn't have a default public constructor or a constructor taking arguments which are already registered in your DI.
You might need to provide the specific instance yourself if the class doesn't have public constructor:
kernel
.Bind<IEntityCache>()
.ToMethod(context => ...return your specific instance here...)
.InSingletonScope();
for example:
kernel
.Bind<IEntityCache>()
.ToMethod(context => EntityCache.Instance)
.InSingletonScope();

Related

How does Guice inject classes without an #Inject-annotated constructor?

I'm trying to understand how DI is used in our codebase (Kotlin). We are using google guice for dependency injection.
Here is a sample class:
class ServiceClass #Inject construct(
private val depA: DepA,
private val depB: DepB
) { ........ }
In Module class:
#Provides
fun provideDepA(): DepA {
//constructs DepA object and returns it
}
DepB class:
class DepB { .... }
As far as I know for the variables annotated with #Inject, Google Guice will look to resolve those dependencies using module class. So it makes sense how DepA object is injected.
But what about DepB? How are we able to inject DepB without specifying it anywhere?
Guice bindings that are not declared in modules are known as Just-in-time Bindings, and by default Guice is willing to call constructors that take zero arguments:
Guice Wiki: JustInTimeBindings
Guice can create bindings for concrete types by using the type's injectable constructor. Guice considers a constructor injectable if:
(recommended) The constructor is explicitly annotated with #Inject (both com.google.inject.Inject and javax.inject.Inject are supported).
or, the constructor takes zero arguments, and
the constructor is non-private and defined in a non-private class (Guice supports private constructor only when it is defined in a private class, however, private constructors are not recommended because they can be slow in Guice due to the cost of reflection).
the injector has not opted in to require explicit #Inject constructor, see explicit #Inject constructors section below.
If you haven't required explicit bindings and you have a public no-arg constructor, Guice will call it as if you had marked it with #Inject. This is in contrast to Dagger, which will only call #Inject-annotated constructors:
Dagger Dev Guide
If your class has #Inject-annotated fields but no #Inject-annotated constructor, Dagger will inject those fields if requested, but will not create new instances. Add a no-argument constructor with the #Inject annotation to indicate that Dagger may create instances as well.
...
Classes that lack #Inject annotations cannot be constructed by Dagger.
In both Guice and Dagger you can construct the objects yourself in #Provides methods, and in Guice you can also use a Module to explicitly bind to a constructor with arguments and without an #Inject constructor.

What is the Equivalent of PropertiesAutoWired of Autofac in Ninject

In Autofac we have PropertiesAutoWired. Its written there
If the component is a reflection component, use the PropertiesAutowired() modifier to inject properties.
Appears that we should use this when we need to do property injection. So I want to know what would it be in case of Ninject.
Ninject doesn't feature an equivalent to Autofacs PropertiesAutowired(). Instead one marks properties with an attribute [Inject] - the binding of the component is unaffected:
public class FooBar
{
// will be injected
[Inject]
public IDependency Dependency { get; set; }
// will not be injected
public IFalaffel Falaffel {get; set;
}
The binding is not affected. For example
Bind<FooBar>().ToSelf();
is perfectly valid and (attributed) properties will be injected.
Also see the Property Injection documentation on the ninject wiki.
Furthermore note, that constructor injection is the preferred alternative. You should only use property injection in case you can't use constructor injection or some other special circumstances, like you cannot get rid of an inheritance hierarchy and don't want to pass constructor parameters down 10 steps in a class hierarchy...
Alternative to using Attributes
If you don't want to clutter your code with references to Ninject, you can also do property injection like this:
Bind<FooBar>().ToSelf()
.OnActivation((ctx, instance) => instance.Dependency = ctx.Kernel.Get<IDependency>());

Controlling lifetime of objects created by factory generated by ToFactory()

I am using the following Ninject related nuget packages in an MVC 5 WebAPI application:
Ninject.MVC5
Ninject.Extensions.Factory
ninject.extensions.conventions
I have a simple repository and a corresponding factory class like so:
public interface ITaskRunner
{
void Run();
}
public interface IRepository<T> where T: class
{
T[] GetAll();
}
public interface IRepositoryFactory<T> where T: class
{
IRepository<T> CreateRepository();
}
I have setup the Ninject bindings using ToFactory() from Ninject.Extensions.Factory like so:
kernel.Bind<ITaskRunner>().To<TaskRunner>().InSingletonScope();
kernel.Bind(typeof(IRepository<>)).To(typeof(Repository<>)).InRequestScope();
kernel.Bind<IRepositoryFactory<Contact>>().ToFactory();
I am using the factory in the following class:
public class TaskRunner : ITaskRunner
{
//MyTask is a simple POCO class(not shown for brevity)
IRepositoryFactory<MyTask> repoFactory = null;
IRepository<MyTask> repo = null;
public TaskRunner(IRepositoryFactory<MyTask> repoFactory)
{
this.repoFactory = repoFactory;
repo = repoFactory.CreateRepository();
}
//implementation elided
}
I am noticing that the call to repoFactory.CreateRepository() always returns the same instance of the factory (dynamic proxy) that Ninject generates.
Question : Is there a way to change/control this behavior and set a "lifetime" such as Transient, PerThread etc. for the instance that "CreateRepository" returns?
In this particular case, tasks might be processed asynchronously on multiple threads and the repository is not thread safe and hence singleton behavior for the instance returned from "CreateRepository" is not desirable.
I'm not sure what you are trying to achieve, but results you are seeing are quite expected because your TaskRunner is bound as Singleton (so constructed once), and you retrieve your repository in the TaskRunner constructor, which again happens once, and so repo is always the same instance. Note this happens regardless of how you bind IRepository and IRepositoryFactory, see Captive Dependency post by Mark Seemann for details http://blog.ploeh.dk/2014/06/02/captive-dependency/.
In fact, if you need to create repo in the constructor, you could just inject IRepository itself. The power of the Factory extension lies in the fact that it allows to resolve instances at runtime, not construction time. For example, if your TaskRunner has Run() method, you can create repository in it, so each task to run can have its own instance.

Ninject Factory - "new" object being passed in instead of one called in factory method

I am using the Ninject Factory Extensions so that I can create objects that have services injected plus custom values
so:
public interface IGameOperationsFactory
{
ISpinEvaluator Create(GameArtifact game);
IReelSpinner CreateSpinner(GameArtifact game);
}
Then in module:
Bind<IGameOperationsFactory>().ToFactory().InSingletonScope();
Bind<ISpinEvaluator>().To<DefaultSpinEvaluatorImpl>();
Bind<IReelSpinner>().To<DefaultReelSpinnerImpl>();
The actual factory gets injected in a classes' constructor and is then used like:
_spinner = _factory.CreateSpinner(_artifact);
_spinEval = _factory.Create(_artifact);
Where _artifact is of type GameArtifact
Then in each of the implementation's constructors services plus the passed in objects are injected. The GameArtifact is successfully passed in the first constructor, and in the second one a "new" GameArtifact is passed in, i.e. not a null one but one with just default values as if the framework just called
new GameArtifact()
instead of passing in the already existing one!
The Constructor for the two objects is very similar, but the one that doesn't work looks like:
[Inject]
public DefaultReelSpinnerImpl(GameArtifact ga, IGameOperationsFactory factory, IRandomService serv)
{
_rand = serv;
_ra = ga.Reels;
_mainReels = factory.Create(_ra);
_winLine = ga.Config.WinLine;
}
Where the factory and serv are injected by Ninject and ga is SUPPOSED to be passed in via the factory.
Anyone have a clue why a new "fresh" object is passed in rather than the one I passed in??
I have rewritten you sample a little bit, and it seems to work fine. Could you provide more detailed code sample?
My implementation
I have changed verb Create to Get to match Ninject conventions
public interface IGameOperationsFactory
{
ISpinEvaluator GetSpinEvaluator(GameArtifact gameArtifact);
IReelSpinner GetReelSpinner(GameArtifact gameArtifact);
}
Ninject configuration
I have added named bindings to configure factory
Bind<ISpinEvaluator>()
.To<DefaultSpinEvaluatorImpl>()
.Named("SpinEvaluator");
Bind<IReelSpinner>()
.To<DefaultReelSpinnerImpl>()
.Named("ReelSpinner");
Bind<IGameOperationsFactory>()
.ToFactory();
ps: full sample with tests

How do you use method injection with Ninject?

I have a class which needs to use an IRepository for one method in it's class.
Ideally, I would like to avoid having to resolve this dependency into the class's constructor, and so I found method level injection in Ninject and was wondering how this works?
I understand how to set it up. What I'm confused about is how to call it?
Example:
class SomeClassThatUsesRepository
{
[Inject]
public void QueryForSomeStuff(IRepository repository)
{
//do some stuff
}
}
My problem is how do I call this method without specifying an IRepository?
var someClass = Kernel.Resolve<SomeClassThatUsesRepository>();
would work if I was using the constructor, but I want to call a method.
How do I call a method using Ninject method injection?
I'm afraid method injection doesn't work this way - it's just one of the ways to inject dependencies into an object during its construction (you can inject your dependencies through constructor parameters, through properties, fields or methods). Method injection is useful if your class takes its dependencies by Java-style setter methods like
public void SetRepository(IRepository repository) { ... }
If it is marked with [Inject] attribute, you don't need to call this methods directly, it is to be called by Ninject during the initialization to pass the IRepository object into your resolved object.
So I believe your QueryForSomeStuff method is being called when you resove your SomeClassThatUsesRepository.
Confirmed that method injection doesn't work as intended. Got a custom MVC attribute class and wanted to use an injected object inside it. Did not pass it
into the constructor and added method
[Ninject.Inject]
public void ResolveDI(ISettingStore store)
{
ConfigHelper = store;
}
This method was never called and ConfigHelper was null when the attribute's OnActionExecuting was called.