C# 尝试基于在autofac中运行时传递的泛型类型解析接口实现

C# 尝试基于在autofac中运行时传递的泛型类型解析接口实现,c#,generics,autofac,C#,Generics,Autofac,我想根据运行时传递的输入参数的类型,从autofac解析特定的接口实现 在我的代码中,我有不同的IMyTask实现: IData myData = input.MyData; taskResolver.GetTask(myData); 我得到请求的服务尚未注册错误 如果我尝试为硬编码的IData类型解析它,它会工作: var myTask = _componentContext.Resolve<IMyTask<SillyData>>(); // works! MyS

我想根据运行时传递的输入参数的类型,从autofac解析特定的接口实现

在我的代码中,我有不同的
IMyTask
实现:

 IData myData = input.MyData;
 taskResolver.GetTask(myData);
我得到
请求的服务尚未注册
错误

如果我尝试为硬编码的
IData
类型解析它,它会工作:

var myTask = _componentContext.Resolve<IMyTask<SillyData>>(); // works! MySillyTask resolved
我如何呼叫
GetTask

 IData myData = input.MyData;
 taskResolver.GetTask(myData);

我想我意识到这是因为
T
IData
而不是导致代码失败的实现。虽然我已将代码更改为使用命名实例并返回非泛型的“IMyTask”,但我仍然对是否可以使用autofac以我最初打算的方式解决它感兴趣。

您没有提供调用此的代码,但我怀疑问题在于类型
t
基于您调用的代码所知道的内容,不是
输入的实际类型
。如果调用代码将其称为
GetTask(obj)
我怀疑它会起作用,但我假设您的
obj
是一个
IData
,恰好是一个
SillyData

如果需要调用泛型方法而不事先知道类型,则必须使用反射。您可以使用
input.GetType()
获取真正的底层类型,然后使用
MakeGenericType
生成
ITask
,然后使用
MakeGenericMethod
调用
Resolve

下面是另一个堆栈溢出问题,它将向您展示如何通过传递类型参数来调用泛型:


我对AutFac了解不多,但我认为
component.Resolve(…)
有一个接受类型的重载

我成功地用Ninject做了类似的事情

    public IMyTask GetTask<T>(T input) where T : IData
    {
        var taskType = typeof(IMyTask<>);
        var inputType = input.GetType();

        var genericType = taskType.MakeGenericType(inputType);
        return (IMyTask)_componentContext.Resolve(genericType);
    }
公共IMyTask GetTask(T输入),其中T:IData
{
var taskType=typeof(IMyTask);
var inputType=input.GetType();
var genericType=taskType.MakeGenericType(inputType);
return(IMyTask)\u componentContext.Resolve(genericType);
}

喜欢这个问题。您是否尝试过使用注入式
Func
Func
,其中消费类中指定了
T
?我在您的答案中将
typeof(T)
更改为
input.GetType()
,这正是我想要的。谢谢。我也改为返回
IMyTask
,而不是一般版本。我可以使用T来派生要使用的实现,但返回一个调用代码不关心
T
The requested service 'Whatever.Tasks.IMyTask`1[[Whatever.Inputs.IData, Whatever, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]]' has not been registered. To avoid this exception, either register a component to provide the service, check for service registration using IsRegistered(), or use the ResolveOptional() method to resolve an optional dependency.
 IData myData = input.MyData;
 taskResolver.GetTask(myData);
    public IMyTask GetTask<T>(T input) where T : IData
    {
        var taskType = typeof(IMyTask<>);
        var inputType = input.GetType();

        var genericType = taskType.MakeGenericType(inputType);
        return (IMyTask)_componentContext.Resolve(genericType);
    }