无法将解析的对象强制转换为通用抽象autofac C#

无法将解析的对象强制转换为通用抽象autofac C#,c#,asp.net,asp.net-core,autofac,C#,Asp.net,Asp.net Core,Autofac,嘿,我尝试将我的对象转换为这个对象应该实现的接口。但在执行代码期间,我有以下错误: 无法将GetTreeHandler类型的对象强制转换为IQueryHandler,IQuery 为什么??一切似乎都很好 有没有不使用动态的想法 QueryDispatcher public async Task<TResult> ExecuteAsync<TResult>(IQuery<TResult> query) { if (query =

嘿,我尝试将我的对象转换为这个对象应该实现的接口。但在执行代码期间,我有以下错误:

无法将GetTreeHandler类型的对象强制转换为IQueryHandler,IQuery

为什么??一切似乎都很好

有没有不使用动态的想法

QueryDispatcher

    public async Task<TResult> ExecuteAsync<TResult>(IQuery<TResult> query)
    {
        if (query == null)
        {
            throw new ArgumentNullException("Query can not be null.");
        }

        var handlerType = typeof (IQueryHandler<,>).MakeGenericType(query.GetType(), typeof (TResult));
        var handler = _context.Resolve(handlerType);

        IQueryHandler<IQuery<TResult>, TResult> castedHandler = (IQueryHandler<IQuery<TResult>, TResult>) handler;

        return (TResult) await castedHandler.ExecuteAsync(query);    
    }   
公共异步任务ExecuteAsync(IQuery查询)
{
if(查询==null)
{
抛出新ArgumentNullException(“查询不能为null”);
}
var handlerType=typeof(IQueryHandler).MakeGenericType(query.GetType(),typeof(TResult));
var handler=_context.Resolve(handlerType);
IQueryHandler castedHandler=(IQueryHandler)处理程序;
return(TResult)wait castedHandler.ExecuteAsync(query);
}   
GetTreeHandler

   public class GetTreeHandler : IQueryHandler<GetTree, Tree>
    {
        private readonly ProductContext _context;
        public string Name { get; set; }
        public GetTreeHandler(ProductContext context)
        {
            _context = context;
        }
        public async Task<Tree> ExecuteAsync(GetTree query)
            =>  await Task.FromResult(
                    _context.Trees.FirstOrDefault(x => x.Id == query.Id)
                );
    }
公共类GetTreeHandler:IQueryHandler { 私有只读ProductContext\u上下文; 公共字符串名称{get;set;} 公共GetTreeHandler(ProductContext上下文) { _上下文=上下文; } 公共异步任务ExecuteAsync(GetTree查询) =>等待任务.FromResult( _context.Trees.FirstOrDefault(x=>x.Id==query.Id) ); } 编辑

我当前的解决方案(部分有效):

公共异步任务ExecuteAsync(IQuery查询),其中TResult:class
{
if(查询==null)
{
抛出新ArgumentNullException(“查询不能为null”);
}
var handlerType=typeof(IQueryHandler).MakeGenericType(query.GetType(),typeof(TResult));
var handler=_context.Resolve(handlerType);
返回等待(任务)
handler.GetType()
.GetMethod(“ExecuteAsync”)
.Invoke(处理程序,新对象[]{query});
}  
为什么部分? 例如:处理人员:

不起作用:

public class GetIndexesHandler : IQueryHandler<GetIndexes, IEnumerable<AssocIndexDto>>
公共类GetIndexesHandler:IQueryHandler
作品:

public class GetIndexesHandler : IQueryHandler<GetIndexes,AssocIndexDto>
公共类GetIndexesHandler:IQueryHandler
正如您所看到的,这两个类实现了相同的接口,但第二个参数类型不同

问题是Resolve方法找不到已注册的服务,但如果我尝试调试此代码,我可以看到所需的服务已正确注册,但找不到


您知道如何解决它吗?

您正在尝试将
IQueryHandler
强制转换为
IQueryHandler
,但只有当
IQueryHandler
被指定为:

interface IQueryHandler<out TQuery, TResult>
另一个选项是指定并注册一个泛型包装器类型,该类型实现了一个缺少
TQuery
泛型类型的接口。这样,您可以防止同时使用
动态

public interface IWrapper<TResult>
{
    Task<TResult> ExecuteAsync(IQuery<TResult> query);
}

public async Task<TResult> ExecuteAsync<TResult>(IQuery<TResult> query)
{
    var wrapperType =
        typeof(Wrapper<,>).MakeGenericType(query.GetType(), typeof(TResult));
    var wrapper = (IWrapper<TResult>)_context.Resolve(wrapperType);
    return wrapper.ExecuteAsync(query);
}

// Don't forget to register this type by itself in Autofac.
public class Wrapper<TQuery, TResult> : IWrapper<TResult>
{
    private readonly IQueryHandler<TQuery, TResult> handler;
    public Wrapper(IQueryHandler<TQuery, TResult> handler) { this.handler = handler; }
    Task<TResult> IWrapper<TResult>.ExecuteAsync(IQuery<TResult> query) =>
        this.handler.ExecuteAsync((TQuery)query);
}
公共接口IWrapper
{
任务执行同步(IQuery查询);
}
公共异步任务ExecuteAsync(IQuery查询)
{
变量包装器类型=
typeof(Wrapper).MakeGenericType(query.GetType(),typeof(TResult));
var wrapper=(IWrapper)\ u context.Resolve(wrapperType);
返回wrapper.ExecuteAsync(查询);
}
//不要忘记在Autofac中自行注册此类型。
公共类包装器:IWrapper
{
私有只读IQueryHandler处理程序;
公共包装器(IQueryHandler){this.handler=handler;}
任务IWrapper.ExecuteAsync(IQuery)=>
this.handler.ExecuteAsync((TQuery)查询);
}

不,它没有_context.Resolve返回我“object”类型,我无法对“object”类型执行“ExecuteAsync”方法,所以我决定将其强制转换到适当的接口。
GetTreeHandler
implement
IQueryHandler
,但不是
IQueryHandler
。但是GetTree实现IQuery,所以它应该是正确的,不是吗?有没有机会不用dynamic来做这件事?假设我找到了解决方案,但我不知道这是否是一个好方法。特别是我指的是性能。反射机制是否使用任何动态类型的底层?嗯,我将尝试您的解决方案,因为它看起来很有意义,但我可能找到了解决方案,但它无法正常工作。你想看看我的溶液吗?(编辑部分有问题)@bielu000:你有两个选择,这两个都在我的答案中给出。您使用反射和调用的选项将无法正常工作,因为调用将使用调用异常包装任何抛出的异常,这将混淆日志文件并使处理特定异常(例如验证异常)变得复杂从业务层。编辑:我的错误是找不到处理程序;)请不要为此烦恼;)感谢您的帮助,我将尝试使用您的解决方案改进我的解决方案。wprapper在我的容器中的注册有问题。它抛出包装器尚未注册的异常。但在我看来,我做得对:builder.RegisterGeneric(typeof(querybushwrapper)).As(typeof(iquerybushwrapper)).InstancePerDependency();
public async Task<TResult> ExecuteAsync<TResult>(IQuery<TResult> query)
{
    var handlerType = 
        typeof(IQueryHandler<,>).MakeGenericType(query.GetType(), typeof(TResult));
    dynamic handler = _context.Resolve(handlerType);
    return (TResult)await castedHandler.ExecuteAsync((dynamic)query);    
}
public interface IWrapper<TResult>
{
    Task<TResult> ExecuteAsync(IQuery<TResult> query);
}

public async Task<TResult> ExecuteAsync<TResult>(IQuery<TResult> query)
{
    var wrapperType =
        typeof(Wrapper<,>).MakeGenericType(query.GetType(), typeof(TResult));
    var wrapper = (IWrapper<TResult>)_context.Resolve(wrapperType);
    return wrapper.ExecuteAsync(query);
}

// Don't forget to register this type by itself in Autofac.
public class Wrapper<TQuery, TResult> : IWrapper<TResult>
{
    private readonly IQueryHandler<TQuery, TResult> handler;
    public Wrapper(IQueryHandler<TQuery, TResult> handler) { this.handler = handler; }
    Task<TResult> IWrapper<TResult>.ExecuteAsync(IQuery<TResult> query) =>
        this.handler.ExecuteAsync((TQuery)query);
}