Autofac.Core.DependencyResolutionException: 类型 '' 的表达式不能用于 Autofac 6.2 中的 return 类型 'System.Object'
Autofac.Core.DependencyResolutionException: Expression of type '' cannot be used for return type 'System.Object' in Autofac 6.2
我这里有代码,曾经在 Autofac 2.6 中工作,但现在在 Autofac 6.2 中不再工作:
class Program
{
static void Main(string[] args)
{
Holder holder = null;
Build(c =>
{
holder = new Holder() { Verifiers = c.Resolve<Verifiers>() };
});
var res = holder.Verifiers;
Console.WriteLine("Success");
}
private static void Build(Action<IContainer> container)
{
var builder = new ContainerBuilder();
builder.RegisterAssemblyTypes(typeof(Verifiers).Assembly).AsSelf().AsImplementedInterfaces();
builder.RegisterType<ConsoleOutput>().As<IOutput>();
builder.RegisterGeneric(typeof(EntityDisplay<>.Params));
builder.RegisterGeneric(typeof(EntityDisplayFactory<,>));
builder.Register<Func<DisplayFactories>>(c => () => new DisplayFactories() { Instances = c.Resolve<IEntityDisplayFactory<object>>() });
container(builder.Build());
}
}
public interface IOutput
{
void Write(string content);
}
public class ConsoleOutput : IOutput
{
public ConsoleOutput()
{
}
public void Write(string content)
{
Console.WriteLine(content);
}
}
public interface IEntityDisplay
{
void Display(object parameter);
}
public class EntityDisplay<T> : IEntityDisplay
{
public struct Params
{
private readonly IOutput _output;
public Params(IOutput output)
{
_output = output;
}
}
private readonly T _entity;
public EntityDisplay(T entity)
{
_entity = entity;
}
public void Display(object parameter)
{
}
}
public interface IEntityDisplayFactory<in T>
{
IEntityDisplay Create(T entity);
}
public class InstanceEntityDisplayFactory : EntityDisplayFactory<object, object>
{
public InstanceEntityDisplayFactory(EntityDisplay<object>.Params parameters) : base(parameters)
{
}
}
public class EntityDisplayFactory<T, I> : IEntityDisplayFactory<T>
{
private readonly EntityDisplay<T>.Params _param;
public EntityDisplayFactory(EntityDisplay<T>.Params parameters)
{
_param = parameters;
}
public IEntityDisplay Create(T entity)
{
return new EntityDisplay<T>(entity);
}
}
public class DisplayFactories
{
public IEntityDisplayFactory<object> Instances { get; set; }
}
public class Verifiers
{
private readonly DisplayFactories _displayFunc;
public Verifiers(Func<DisplayFactories> displayFunc)
{
_displayFunc = displayFunc();
}
public void Show()
{
DisplayFactories res = _displayFunc;
res.Instances.Create(null);
}
}
public class Holder
{
public Verifiers Verifiers { get; set; }
}
Autofac 6.2 抛出的异常是
> Autofac.Core.DependencyResolutionException HResult=0x80131500
> Message=An exception was thrown while activating
> AutofacTest46.InstanceEntityDisplayFactory. Source=Autofac
> StackTrace: at
> Autofac.Core.Resolving.Middleware.ActivatorErrorHandlingMiddleware.Execute(ResolveRequestContext
> context, Action`1 next) at
> Autofac.Core.Resolving.Pipeline.ResolvePipelineBuilder.<>c__DisplayClass14_0.<BuildPipeline>b__1(ResolveRequestContext
> ctxt) at
> Autofac.Core.Pipeline.ResolvePipeline.Invoke(ResolveRequestContext
> ctxt) at
> Autofac.Core.Resolving.Middleware.RegistrationPipelineInvokeMiddleware.Execute(ResolveRequestContext
> context, Action`1 next) at
> Autofac.Core.Resolving.Pipeline.ResolvePipelineBuilder.<>c__DisplayClass14_0.<BuildPipeline>b__1(ResolveRequestContext
> ctxt) at
> Autofac.Core.Resolving.Middleware.SharingMiddleware.Execute(ResolveRequestContext
> context, Action`1 next) at
> Autofac.Core.Resolving.Pipeline.ResolvePipelineBuilder.<>c__DisplayClass14_0.<BuildPipeline>b__1(ResolveRequestContext
> ctxt) at
> Autofac.Core.Resolving.Middleware.ScopeSelectionMiddleware.Execute(ResolveRequestContext
> context, Action`1 next) at
> Autofac.Core.Resolving.Pipeline.ResolvePipelineBuilder.<>c__DisplayClass14_0.<BuildPipeline>b__1(ResolveRequestContext
> ctxt) at
> Autofac.Core.Resolving.Middleware.CircularDependencyDetectorMiddleware.Execute(ResolveRequestContext
> context, Action`1 next) at
> Autofac.Core.Resolving.Pipeline.ResolvePipelineBuilder.<>c__DisplayClass14_0.<BuildPipeline>b__1(ResolveRequestContext
> ctxt) at
> Autofac.Core.Pipeline.ResolvePipeline.Invoke(ResolveRequestContext
> ctxt) at
> Autofac.Core.Resolving.ResolveOperation.GetOrCreateInstance(ISharingLifetimeScope
> currentOperationScope, ResolveRequest request) at
> Autofac.Core.Resolving.Pipeline.DefaultResolveRequestContext.ResolveComponent(ResolveRequest
> request) at
> Autofac.ResolutionExtensions.TryResolveService(IComponentContext
> context, Service service, IEnumerable`1 parameters, Object& instance)
> at Autofac.ResolutionExtensions.ResolveService(IComponentContext
> context, Service service, IEnumerable`1 parameters) at
> Autofac.ResolutionExtensions.Resolve[TService](IComponentContext
> context, IEnumerable`1 parameters) at
> Autofac.ResolutionExtensions.Resolve[TService](IComponentContext
> context) at
> AutofacTest46.Program.<>c__DisplayClass1_0.<Build>b__1() in D:\.net
> Samples project\May 2021\AutofacTest46\Program.cs:line 34 at
> AutofacTest46.Verifiers..ctor(Func`1 displayFunc) in D:\.net Samples
> project\May 2021\AutofacTest46\Outputs.cs:line 94 at
> Autofac.Core.Activators.Reflection.BoundConstructor.Instantiate()
>
> This exception was originally thrown at this call stack:
> [External Code]
>
> Inner Exception 1: ArgumentException: Expression of type
> 'AutofacTest46.EntityDisplay`1+Params[System.Object]' cannot be used
> for return type 'System.Object'
- 为什么在 Autofac 6.2 中会发生这种情况?
- 如何解决这个错误?
问题是 EntityDisplay<>.Params
是一个值类型 - struct
。将其更改为 class
就可以了。
由于 DI 和反射以及诸如此类的东西目前结合在一起的方式,我们必须能够将基于反射的操作的输出转换为 object
。 You can see the current wire-up code here. 不幸的是,值类型的构造函数调用程序没有 return object
,所以我们无法解析它,一切都崩溃了。
我们可能会接受带有修复代码的拉取请求,但是 DI 到值类型通常不是人们做的事情。
无论如何,切换到 class
就可以了。
顺便说一句,这有点难以完成 - 在以后的问题中,它可能有助于减少重现(例如,你不需要 Holder
class所有,这只是噪音;你不需要 Verifiers
,等等。在问题中的异常消息上获得更清晰的格式也会有所帮助,并确保包括所有内部异常。关键是指向构造函数调用程序的内部异常。我只能通过 copy/pasting 这段代码并进行调试才能看到它,不幸的是,我通常没有时间去做。我不得不继续回答这一个。
我这里有代码,曾经在 Autofac 2.6 中工作,但现在在 Autofac 6.2 中不再工作:
class Program
{
static void Main(string[] args)
{
Holder holder = null;
Build(c =>
{
holder = new Holder() { Verifiers = c.Resolve<Verifiers>() };
});
var res = holder.Verifiers;
Console.WriteLine("Success");
}
private static void Build(Action<IContainer> container)
{
var builder = new ContainerBuilder();
builder.RegisterAssemblyTypes(typeof(Verifiers).Assembly).AsSelf().AsImplementedInterfaces();
builder.RegisterType<ConsoleOutput>().As<IOutput>();
builder.RegisterGeneric(typeof(EntityDisplay<>.Params));
builder.RegisterGeneric(typeof(EntityDisplayFactory<,>));
builder.Register<Func<DisplayFactories>>(c => () => new DisplayFactories() { Instances = c.Resolve<IEntityDisplayFactory<object>>() });
container(builder.Build());
}
}
public interface IOutput
{
void Write(string content);
}
public class ConsoleOutput : IOutput
{
public ConsoleOutput()
{
}
public void Write(string content)
{
Console.WriteLine(content);
}
}
public interface IEntityDisplay
{
void Display(object parameter);
}
public class EntityDisplay<T> : IEntityDisplay
{
public struct Params
{
private readonly IOutput _output;
public Params(IOutput output)
{
_output = output;
}
}
private readonly T _entity;
public EntityDisplay(T entity)
{
_entity = entity;
}
public void Display(object parameter)
{
}
}
public interface IEntityDisplayFactory<in T>
{
IEntityDisplay Create(T entity);
}
public class InstanceEntityDisplayFactory : EntityDisplayFactory<object, object>
{
public InstanceEntityDisplayFactory(EntityDisplay<object>.Params parameters) : base(parameters)
{
}
}
public class EntityDisplayFactory<T, I> : IEntityDisplayFactory<T>
{
private readonly EntityDisplay<T>.Params _param;
public EntityDisplayFactory(EntityDisplay<T>.Params parameters)
{
_param = parameters;
}
public IEntityDisplay Create(T entity)
{
return new EntityDisplay<T>(entity);
}
}
public class DisplayFactories
{
public IEntityDisplayFactory<object> Instances { get; set; }
}
public class Verifiers
{
private readonly DisplayFactories _displayFunc;
public Verifiers(Func<DisplayFactories> displayFunc)
{
_displayFunc = displayFunc();
}
public void Show()
{
DisplayFactories res = _displayFunc;
res.Instances.Create(null);
}
}
public class Holder
{
public Verifiers Verifiers { get; set; }
}
Autofac 6.2 抛出的异常是
> Autofac.Core.DependencyResolutionException HResult=0x80131500
> Message=An exception was thrown while activating
> AutofacTest46.InstanceEntityDisplayFactory. Source=Autofac
> StackTrace: at
> Autofac.Core.Resolving.Middleware.ActivatorErrorHandlingMiddleware.Execute(ResolveRequestContext
> context, Action`1 next) at
> Autofac.Core.Resolving.Pipeline.ResolvePipelineBuilder.<>c__DisplayClass14_0.<BuildPipeline>b__1(ResolveRequestContext
> ctxt) at
> Autofac.Core.Pipeline.ResolvePipeline.Invoke(ResolveRequestContext
> ctxt) at
> Autofac.Core.Resolving.Middleware.RegistrationPipelineInvokeMiddleware.Execute(ResolveRequestContext
> context, Action`1 next) at
> Autofac.Core.Resolving.Pipeline.ResolvePipelineBuilder.<>c__DisplayClass14_0.<BuildPipeline>b__1(ResolveRequestContext
> ctxt) at
> Autofac.Core.Resolving.Middleware.SharingMiddleware.Execute(ResolveRequestContext
> context, Action`1 next) at
> Autofac.Core.Resolving.Pipeline.ResolvePipelineBuilder.<>c__DisplayClass14_0.<BuildPipeline>b__1(ResolveRequestContext
> ctxt) at
> Autofac.Core.Resolving.Middleware.ScopeSelectionMiddleware.Execute(ResolveRequestContext
> context, Action`1 next) at
> Autofac.Core.Resolving.Pipeline.ResolvePipelineBuilder.<>c__DisplayClass14_0.<BuildPipeline>b__1(ResolveRequestContext
> ctxt) at
> Autofac.Core.Resolving.Middleware.CircularDependencyDetectorMiddleware.Execute(ResolveRequestContext
> context, Action`1 next) at
> Autofac.Core.Resolving.Pipeline.ResolvePipelineBuilder.<>c__DisplayClass14_0.<BuildPipeline>b__1(ResolveRequestContext
> ctxt) at
> Autofac.Core.Pipeline.ResolvePipeline.Invoke(ResolveRequestContext
> ctxt) at
> Autofac.Core.Resolving.ResolveOperation.GetOrCreateInstance(ISharingLifetimeScope
> currentOperationScope, ResolveRequest request) at
> Autofac.Core.Resolving.Pipeline.DefaultResolveRequestContext.ResolveComponent(ResolveRequest
> request) at
> Autofac.ResolutionExtensions.TryResolveService(IComponentContext
> context, Service service, IEnumerable`1 parameters, Object& instance)
> at Autofac.ResolutionExtensions.ResolveService(IComponentContext
> context, Service service, IEnumerable`1 parameters) at
> Autofac.ResolutionExtensions.Resolve[TService](IComponentContext
> context, IEnumerable`1 parameters) at
> Autofac.ResolutionExtensions.Resolve[TService](IComponentContext
> context) at
> AutofacTest46.Program.<>c__DisplayClass1_0.<Build>b__1() in D:\.net
> Samples project\May 2021\AutofacTest46\Program.cs:line 34 at
> AutofacTest46.Verifiers..ctor(Func`1 displayFunc) in D:\.net Samples
> project\May 2021\AutofacTest46\Outputs.cs:line 94 at
> Autofac.Core.Activators.Reflection.BoundConstructor.Instantiate()
>
> This exception was originally thrown at this call stack:
> [External Code]
>
> Inner Exception 1: ArgumentException: Expression of type
> 'AutofacTest46.EntityDisplay`1+Params[System.Object]' cannot be used
> for return type 'System.Object'
- 为什么在 Autofac 6.2 中会发生这种情况?
- 如何解决这个错误?
问题是 EntityDisplay<>.Params
是一个值类型 - struct
。将其更改为 class
就可以了。
由于 DI 和反射以及诸如此类的东西目前结合在一起的方式,我们必须能够将基于反射的操作的输出转换为 object
。 You can see the current wire-up code here. 不幸的是,值类型的构造函数调用程序没有 return object
,所以我们无法解析它,一切都崩溃了。
我们可能会接受带有修复代码的拉取请求,但是 DI 到值类型通常不是人们做的事情。
无论如何,切换到 class
就可以了。
顺便说一句,这有点难以完成 - 在以后的问题中,它可能有助于减少重现(例如,你不需要 Holder
class所有,这只是噪音;你不需要 Verifiers
,等等。在问题中的异常消息上获得更清晰的格式也会有所帮助,并确保包括所有内部异常。关键是指向构造函数调用程序的内部异常。我只能通过 copy/pasting 这段代码并进行调试才能看到它,不幸的是,我通常没有时间去做。我不得不继续回答这一个。