编写/编写通用Ninject绑定的问题

时间:2012-11-26 16:01:14

标签: c# generics ninject metaprogramming

我有以下类,我用它来对数据库进行特定查询,并创建数据的表示模型以传递回客户端浏览器。

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>'.   

2 个答案:

答案 0 :(得分:3)

我知道这个问题是关于Ninject的,但是如果你正在做这种通用技巧,你可能想尝试Simple Injector。它允许您在一行代码中注册所有IPresentationQuery<TRequest, TResult>实现,如下所示:

container.RegisterManyForOpenGeneric(
    typeof(IPresentationQuery<,>),
    typeof(IPresentationQuery<,>).Assembly);

RegisterManyForOpenGenericSimpleInjector.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>的实现。