Ninject InSingletonScope Inject Single Parameter Every Request

1.1k Views Asked by At

I am using Ninject

I have a class which I am using to hold & build some cached data if needed. It is set up in my Niject binding as follows

    kernel.Bind<IConsistencyCheckCacheHelper>().To<ConsistencyCheckCacheHelper>().InSingletonScope();

The Class has some required dependencies injected into it the first time that the class is created, then that same instance is inject every time.

But in the case that the data needs to be rebuild I need run time dependency injected.

I am using this as a application wide cache,

Any ideas how to do this?

2

There are 2 best solutions below

0
Lord Darth Vader On BEST ANSWER

This may not be the best way to do this but it works, Create 2 Interfaces that represent the same class

public interface DepInterfaceOne
{
    int MethodWithCachedData();

    void InfoRequiredForAtRunTime(object RunTimeObject);
}

public interface DepInterfaceTwo: IConsistencyCheckCacheHelper
{

}

And Set up your binding in this way

         kernel.Bind<DepInterfaceOne>().To<DepInterfaceOneClass>().InSingletonScope();

        kernel.Bind<DepInterfaceOneTwo>().ToMethod(a =>
        {
            DepInterfaceOne toReturn = kernel.Get<DepInterfaceOne>();
            toReturn.InfoRequiredForAtRunTime(HttpContext.Current.Session["InfoRequired"]);
            return toReturn;
        });
0
Scott Hannen On

The Class has some required dependencies injected into it the first time that the class is created, then that same instance is inject every time.

The class has been registered with Ninject as a singleton. That means that the first time Ninject resolves an IConsistencyCheckCacheHelper it will create an instance of ConsistencyCheckCacheHelper, and then it will use that same instance over and over again.

So Ninject isn't injecting the same instance of a dependency into ConsistencyCheckCacheHelper over and over. It's only creating one instance of ConsistencyCheckCacheHelper, so whatever instance of the dependency gets injected into it won't change either.

If you want the dependency within used by ConsistencyCheckCacheHelper to change each time it's resolved then you can't register it as a singleton. You would need to use a different scope.

.InTransientScope() (the default) means that every time a type is resolved a new instance is created.

.InRequestScope() means that a new instance is created for every web request.

It's still a tiny bit more complicated than that. For example, if ConsistencyCheckCacheHelper is registered as transient, a new instance is created each time. But if it depends on something else and that dependency is registered as a singleton, each new instance of ConsistencyCheckCacheHelper will receive the same singleton instance of that dependency.

It's often recommended that we start off with transient dependencies. Unless we specifically need to reuse an instance, the cost of creating new objects likely isn't that great. For a web application, InRequestScope is likely safe. I'd only use singleton scope if I'm sure that I can safely reuse one instance of that class along with one instance if its dependencies and their dependencies and so on.

Ninject object scopes