Ninject 泛型绑定解析抛出 ActivationException

Ninject generic binding resolve throws ActivationException

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

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);
    }
}

并且我在应用程序启动时绑定查询服务和解析器类型。

 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 个步骤,但没有找到任何东西。我应该绑定其他东西吗?

Ninject 无法解析 IQueryHandler<,> 接口。 您需要为其定义绑定。

类似于:

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

希望对您有所帮助。

Ninject 应该知道你的 concreate 类型来绑定接口。我认为您有多个 IQueryHandler<,> 接口的实现,因此您不能手动将它们绑定到接口。

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

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

小心应用正确的程序集(FromThisAssembly 或其他)。

现在您的 Resolve 方法知道可以创建实例。