【问题标题】:Problems writing/compling generic Ninject binding编写/编译通用 Ninject 绑定的问题
【发布时间】:2012-11-14 03:29:43
【问题描述】:

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

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

【问题讨论】:

  • 很高兴看到这个设计与here解释的设计非常相似。

标签: c# generics ninject metaprogramming


【解决方案1】:

您的类型参数的顺序似乎是错误的。您尝试将IPresentationQuery&lt;FooResult, FooRequest&gt; 绑定到IPresentationQuery&lt;FooRequest, FooResult&gt; 的实现。

【讨论】:

  • 感谢您发现这一点,但当我切换请求和结果时仍然无法正常工作。最终得到以下行 kernel.Bind(typeof(IPresentationQuery&lt;FooRequest, FooReqult&gt;)).To(typeof(SpecificFooQuery));
【解决方案2】:

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

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

RegisterManyForOpenGenericSimpleInjector.Extensions 项目的扩展方法,可以像 Simple Injector 一样从 NuGet 下载。

用通用装饰器包装所有这些实现也将是一个单行:

container.RegisterDecorator(
    typeof(IPresentationQuery<,>),
    typeof(ValidationPresentationQueryDecorator<,>));

Simple Injector 的好处在于它的速度非常快,即使在处理通用装饰器时也是如此。 Simple Injector 甚至尊重您的泛型类型约束。您将泛型类型约束添加到装饰器以防止它被包装到某些类型。如果这不可能,您还可以像这样注册一个条件装饰器:

container.RegisterDecorator(
    typeof(IPresentationQuery<,>),
    typeof(ValidationPresentationQueryDecorator<,>),
    context => NeedsValidation(context.ImplementationType));

即使这个注册被优化,提供的谓词也只会被每个封闭的泛型类型调用一次。 RegisterDecorator 方法与 RegisterManyForOpenGeneric 属于同一扩展项目。

【讨论】:

  • 谢谢你,我试试看
  • 您对 Simple Injector 有很多经验吗?我已经进行了几次搜索,发现它在去年年底的一次测试中在性能方面名列前茅。我们正在运行一个 MVC4/WebApi 应用程序,并且遇到了一些性能问题,所以我想知道这是否对我们有所帮助。
  • 有些人可能会说我对 Simple Injector 有一些经验 :-)。如果您有任何问题,请随时在 Stackoverflow 或 Simple Injector 代码项目论坛上提问。
猜你喜欢
  • 2014-01-22
  • 1970-01-01
  • 2022-06-29
  • 1970-01-01
  • 1970-01-01
  • 2016-07-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多