Reputation: 54377
I want to pass an instance of a cache as a dependency to one or more types. When a concrete instance of the cache is instantiated, it must be provided information about the type that will use it.
I realize that this a common task and that injecting cache dependencies appears in various questions/answers; I'm setting up a specific problem I'm having with Ninject.
interface IMethodCache { }
public class MethodCache : IMethodCache
{
public MethodCache( Type type )
{
// type information is used to build unique cache keys
}
}
public class CacheConsumer
{
public CacheConsumer( IMethodCache cache ) { }
}
The Ninject documentation shows how to do just that (using logging as an example):
class ClassThatLogs {
readonly ILog _log;
public ClassThatLogs(ILog log){
_log = log;
}
}
Bind<ILog>().ToMethod( context => LogFactory.CreateLog( context.Request.Target.Type ) );
The previous example shows that context.Request.Target.Type
will contain the type information for the type into which injection occurs.
Furthermore, the comments on context.Request.Target
state:
Gets the target that will receive the injection, if any.
Based on this, I expect to see information about the instance receiving the injection. I setup my binding as follows:
kernel.Bind<IMethodCache>().ToMethod(
ctx =>
{
return new MethodCache( ctx.Request.Target.Type );
} );
But the result is unexpected.
The Type
property of Target
is set to the type being bound (IMethodCache
), not the "target that will receive injection" (CacheConsumer
).
To state it another way: when the dependency is created, I need to pass the injectable's type to it.
I can obtain the desired information by using context.Request.Target.Member.DeclaringType
. However, I'm concerned because I don't know the ramifications of relying on the declaring type and—more importantly—because this seems contrary to the documentation.
StandardKernel
Upvotes: 2
Views: 475
Reputation: 139758
Yes, it seems that the documentation is incomplete/incorrect in this case.
you can get the "target" type information starting from ctx.Request.Target
property but but you need to go "one step further" with using the Member
and the ctx.Request.Target.Member.DeclaringType
as you've already noticed.
So it is completely fine to use the context.Request.Target.Member.DeclaringType
in fact if you check the mentioned Ninject.Extensions.Loggin you will see the following in the
/// <summary>
/// Gets the logger for the specified activation context, creating it if necessary.
/// </summary>
/// <param name="context">The ninject creation context.</param>
/// <returns>The newly-created logger.</returns>
public ILogger GetLogger(IContext context)
{
return this.GetLogger(context.Request.Target.Member.DeclaringType);
}
Upvotes: 4