我有以下类,我用它来对数据库进行特定查询,并创建数据的表示模型以传递回客户端浏览器。
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 { ... };
}
}
它实现了以下通用接口
public interface IPresentationQuery<TRequest, TResult>
where TRequest : class
where TResult : class
{
TResult Get(TRequest request);
}
但是我在编写一个ninject实例化时遇到了问题,这个实例化会为我创建我的对象。这不起作用,但到目前为止我还没有比这更进一步。
kernel.Bind<IPresentationQuery<FooResult, FooRequest>>().To<SpecificFooQuery>();
任何人都可以帮助我解决这个问题,我不确定我哪里出错或者我需要做些什么才能使这项工作。
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>'.
答案 0 :(得分:3)
我知道这个问题是关于Ninject的,但是如果你正在做这种通用技巧,你可能想尝试Simple Injector。它允许您在一行代码中注册所有IPresentationQuery<TRequest, TResult>
实现,如下所示:
container.RegisterManyForOpenGeneric(
typeof(IPresentationQuery<,>),
typeof(IPresentationQuery<,>).Assembly);
RegisterManyForOpenGeneric是SimpleInjector.Extensions项目的扩展方法,可以像简单注入者一样从NuGet下载。
使用通用装饰器包装所有这些实现也是一个单行程序:
container.RegisterDecorator(
typeof(IPresentationQuery<,>),
typeof(ValidationPresentationQueryDecorator<,>));
简单注入器的好处在于它即使在处理通用装饰器时速度也非常快。而Simple Injector甚至尊重您的泛型类型约束。您将一个泛型类型约束添加到装饰器,以防止它被包装到某些类型。如果那是不可能的,你也可以注册这样的条件装饰:
container.RegisterDecorator(
typeof(IPresentationQuery<,>),
typeof(ValidationPresentationQueryDecorator<,>),
context => NeedsValidation(context.ImplementationType));
即使这个注册已经过优化,所提供的谓词也只会在每个封闭的泛型类型中调用一次。 RegisterDecorator方法是与RegisterManyForOpenGeneric
相同的扩展项目的一部分。
答案 1 :(得分:1)
似乎您的类型参数的顺序是错误的。您尝试将IPresentationQuery<FooResult, FooRequest>
绑定到IPresentationQuery<FooRequest, FooResult>
的实现。