簡體   English   中英

Autofac.Core.DependencyResolutionException:類型“”的表達式不能用於 Autofac 6.2 中的返回類型“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'
  1. 為什么在 Autofac 6.2 中會發生這種情況?
  2. 如何解決這個錯誤?

問題是EntityDisplay<>.Params是一個值類型 - 一個struct 將其更改為class就可以了。

由於 DI 和反射以及目前所有其他的方式結合在一起,我們必須能夠將基於反射的操作的 output 轉換為object 您可以在此處查看當前的接線代碼。 不幸的是,值類型的構造函數調用程序不返回object所以我們無法解決它,一切都崩潰了。

我們可能會接受帶有修復代碼的拉取請求,但是人們通常不會做 DI 到值類型的事情。

無論如何,切換到class就可以了。

順便說一句,這有點難以解決 - 在未來的問題中,它可能有助於減少重復次數(例如,你根本不需要Holder class,它只是噪音;你不需要Verifiers等。在問題中獲取更清晰的異常消息格式也會有所幫助,並確保包含所有內部異常。大關鍵是指向構造函數調用程序的內部異常。我只能通過復制看到它/粘貼這段代碼並調試,不幸的是,我通常沒有時間去做。否則我不得不繼續回答這個問題。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM