繁体   English   中英

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

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

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

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

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

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

就像是:

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

希望这可以帮助。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM