Ninject泛型绑定解析抛出ActivationException

时间:2015-03-06 14:56:12

标签: c# generics ninject

我有一个查询处理程序的泛型类型。

public interface IQueryHandler<in TQuery, out TResult>
    where TQuery : IQuery<TResult>
{
    TResult Execute(TQuery query);
}

我有很多这个界面的实现。所以我创建了一个服务来解决这些类型:

    public class QueryService : IQueryService
    {
        private readonly IResolver resolver;

        public QueryService(IResolver resolver)
        {
            this.resolver = resolver;
        }

        public TResult ExecuteQuery<TResult>(IQuery<TResult> query)
        {
            var queryHandlerType = typeof IQueryHandler<,>).MakeGenericType(query.GetType(),  typeof (TResult));
            var queryHandlerImpl = resolver.Resolve(queryHandlerType);

            return (TResult) ((dynamic) queryHandlerImpl).Execute((dynamic) query);
        }
    }

我的解析器类型是使用ninject。

public class Resolver : IResolver
{
    private readonly IKernel container;

    public Resolver(IKernel container)
    {
        this.container = container;
    }

    public object Resolve(Type T)
    {
        return container.Get(T);
    }
}

我在应用程序启动时绑定了Query服务和Resolver类型。

 container.Bind<IResolver>().To<Resolver>();         
 container.Bind<IQueryService>().To<QueryService>();

当应用程序启动时,异常就是抛出 Resolver

的方法
public object Resolve(Type T)
{
    return container.Get(T);
}

            An exception of type 'Ninject.ActivationException' 
    occurred in Ninject.dll but was not handled in user code

            Additional information: Error activating IQueryHandler{PlaceByIdQuery, PlaceByIdQueryResult}       No matching bindings are available,  and the type is not self-bindable.

        Activation path:
1) Ensure that you have defined a binding for IQueryHandler{PlaceByIdQuery, PlaceByIdQueryResult}.

  2) If the binding was defined in a module, ensure that the module has been loaded into the kernel.

  3) Ensure you have not accidentally created more than one kernel.

  4) If you are using constructor arguments, ensure that the parameter name matches the constructors parameter name.

  5) If you are using automatic module loading, ensure the search path and filters are correct.

我检查了5个步骤但没有找到任何东西。我应该绑定其他东西吗?

2 个答案:

答案 0 :(得分:2)

Ninject应该知道你的concreate类型绑定接口。我认为您有多个 IQueryHandler&lt;,&gt; 接口的实现,因此您无法将它们手动绑定到接口。

但Ninject.Extensions.Conventions正在自动执行此操作。 (你可以从nuget下载)

        kernel.Bind(x => x.FromThisAssembly()
                          .IncludingNonePublicTypes()
                          .SelectAllClasses()
                          .InheritedFrom(typeof(IQueryHandler<,>))
                          .BindSingleInterface());

小心应用正确的装配(FromThisAssembly或其他)。

现在你的Resolve方法知道cancreate实例。

答案 1 :(得分:0)

Ninject无法解析IQueryHandler&lt;,&gt;接口。 您需要为它定义绑定。

类似的东西:

container.Bind(typeof(IQueryHandler<,>)).To(typeof(QueryHandler<,>));

希望这有帮助。