Delegate Initial Initiative Using Ninject

I am using Ninject 1.0 and want to be able to add lazy initialization delegates to constructors. So, given the general definition of a delegate:

public delegate T LazyGet<T>(); 

I would just like to bind this to IKernel.Get () so that I can pass a lazy getter to constructors, for example.

 public class Foo { readonly LazyGet<Bar> getBar; public Foo( LazyGet<Bar> getBar ) { this.getBar = getBar; } } 

However, I cannot just call Bind<LazyGet<T>>() because it is an open generic type. I need this to be an open generic one, so I don’t need to bind all the different lazy ones to get explicit types. In the above example, it should be possible to dynamically create a shared delegate that calls IKernel.Get<T>() .

How can this be achieved with Ninject 1.0?

+4
source share
3 answers

I do not quite understand the question, but how could you use reflection? Sort of:

 // the type of T you want to use Type bindType; // the kernel you want to use IKernel k; // note - not compile tested MethodInfo openGet = typeof(IKernel).GetMethod("Get`1"); MethodInfo constGet = openGet.MakeGenericMethod(bindType); Type delegateType = typeof(LazyGet<>).MakeGenericType(bindType); Delegate lazyGet = Delegate.CreateDelegate(delegateType, k, constGet); 

Will using lazyGet let you do what you want? Note that you may also need to call the Foo class by reflection if bindType not known in the compilation context.

0
source

I am pretty sure that the only way to do this (without any dirty reflection code) is to associate your delegate with type parameters. This will mean that you need to do this for each type you use. You could use the BindingGenerator to make it bulk, but it can get a little ugly.

If there is a better solution (clean), I would like to hear it when I came across this problem from time to time.

0
source

From another similar question, I answered:

 public class Module : NinjectModule { public override void Load() { Bind(typeof(Lazy<>)).ToMethod(ctx => GetType() .GetMethod("GetLazyProvider", BindingFlags.Instance | BindingFlags.NonPublic) .MakeGenericMethod(ctx.GenericArguments[0]) .Invoke(this, new object[] { ctx.Kernel })); } protected Lazy<T> GetLazyProvider<T>(IKernel kernel) { return new Lazy<T>(() => kernel.Get<T>()); } } 
0
source

Source: https://habr.com/ru/post/1302369/


All Articles