I have the following class which I’m using to do a specific query on the database and creating a presentation model of data to pass back to the client browser.
public class SpecificFooQuery: IPresentationQuery<FooRequest, FooResult>
{
public SpecificFooQuery(ILogger logger, DbContext context)
{
this.logger = logger;
this.context = context;
}
public FooResult Get(FooRequest request)
{
return new FooResult { ... };
}
}
It implements the following generic interface
public interface IPresentationQuery<TRequest, TResult>
where TRequest : class
where TResult : class
{
TResult Get(TRequest request);
}
But I’m having problems writing a ninject instantiation which will create my object for me. This doesn’t work but I’ve not really got any further than this so far.
kernel.Bind<IPresentationQuery<FooResult, FooRequest>>().To<SpecificFooQuery>();
Can anyone help me out with this, I’m not really sure where I’m going wrong or what I need to do to make this work.
Error 1
The type 'SpecificFooQuery' cannot be used as type parameter
'TImplementation' in the generic type or method
'Ninject.Syntax.IBindingToSyntax<T1>.To<TImplementation>()'.
There is no implicit reference conversion from
'SpecificFooQuery' to 'IPresentationQuery<FooResult,FooRequest>'.
I know this question is about Ninject, but if you’re doing this kind of generic trickery, you might want to try Simple Injector. It allows you to register all
IPresentationQuery<TRequest, TResult>implementations in one single line of code like this:RegisterManyForOpenGeneric is an extension method on the SimpleInjector.Extensions project which can be downloaded from NuGet just as Simple Injector is.
And wrapping all those implementations with a generic decorator would also be a one-liner:
Nice about Simple Injector is that it is blazingly fast, even when dealing with generic decorators. And Simple Injector even respects your generic type constraints. You add a generic type constraint to a decorator to prevent it from being wrapped to certain types. And if that’s not possible, you can also register a conditional decorator like this:
Even this registration is optimized and the supplied predicate will only be called once per closed generic type. The RegisterDecorator method is part of the same Extensions project as
RegisterManyForOpenGenericis.