简体   繁体   English

Ninject通用绑定解析抛出ActivationException

[英]Ninject generic binding resolve throws ActivationException

I have a generic type for query handlers. 我有查询处理程序的通用类型。

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

And I have so many implementation for this interface. 我对此接口有很多实现。 So I created a service to resolve these types: 所以我创建了一个服务来解决这些类型:

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

My resolver type is using ninject. 我的解析器类型使用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);
    }
}

And I bind Query service and Resolver type on application start. 我在应用程序启动时绑定查询服务和解析器类型。

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

When application started an exception is throwing at this method of Resolver : 当应用程序启动时,在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.

I checked 5 steps but not find anything. 我检查了5个步骤,但没有找到任何东西。 Should I bind something else? 我应该捆绑其他东西吗?

Ninject should know your concreate types to bind interfaces. Ninject应该知道您的concreate类型来绑定接口。 I think you have multiple implementation of IQueryHandler<,> interface so you can not bind manually them to interface. 我认为您有IQueryHandler <,>接口的多个实现,因此您不能手动将它们绑定到接口。

But Ninject.Extensions.Conventions is doing this automatically. 但是Ninject.Extensions.Conventions会自动执行此操作。 (you can download from nuget) (您可以从nuget下载)

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

Be careful applying correct assembly(FromThisAssembly or else). 小心应用正确的程序集(FromThisAssembly或其他)。

Now your Resolve method knows cancreate instances. 现在,您的Resolve方法知道可以创建实例了。

Ninject cannot resolve IQueryHandler<,> interface. Ninject无法解析IQueryHandler <,>接口。 You need to define binding for it. 您需要为其定义绑定。

Something like: 就像是:

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

Hope this helps. 希望这可以帮助。

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

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