【问题标题】:Cannot choose between multiple constructors with equal length 1 on type 'System.String' with autofac无法在具有 autofac 的“System.String”类型上的多个等长 1 的构造函数之间进行选择
【发布时间】:2016-04-27 14:27:11
【问题描述】:

我得到了那个例外

抛出异常:Autofac.dll 中的“Autofac.Core.DependencyResolutionException”

附加信息:无法在类型“System.String”的多个长度为 1 的构造函数之间进行选择。注册组件时,使用 UsingConstructor() 配置方法显式选择构造函数。

堆栈跟踪

 at Autofac.Core.Activators.Reflection.MostParametersConstructorSelector.SelectConstructorBinding(ConstructorParameterBinding[] constructorBindings)

当我这样做时

container.Resolve();

我如何注册我的服务

builder.RegisterType<CustomerService>()
       .As<ICustomerProcessingUnit>()
       .WithParameter("MyUrl", AppSettings.Default.MyUrl);

我如何解决我的服务:

var customerService = container.Resolve<CustomerService>();

我的 CustomerService 类

public class CustomerService: CustomerProcessingUnitBase 
    {
        private string myUrl;
        private readonly ISendService sendService;

        public CustomerService(ISendService sendService, string myUrl)
        {
            this.sendService = sendService;
            this.myUrl= myUrl;
        }
}

ICustomerProcessingUnit.cs 文件中:

 public interface ICustomerProcessingUnit
 {
    Task ProcessAsync();
 }

    public abstract class CustomerProcessingUnitBase : ICustomerProcessingUnit
    {
        public abstract Task ProcessAsync();

        public void Process()
        {
            this.ProcessAsync().Wait();
        }
    }

为什么会出现这个异常?

我知道:Cannot choose between multiple constructors with equal length 1 on type 'System.String'

但是Autofac 为什么要创建一个字符串呢?我注入它!请参阅我的 .Register 调用,将字符串作为参数传递。

【问题讨论】:

  • 你能分享一下堆栈跟踪吗?
  • 你能不能只在第一行发布完整的堆栈跟踪蚂蚁? :-)

标签: c# dependency-injection autofac


【解决方案1】:

我使用 Autofac 3.5.2 使用下面的代码创建了一个测试应用程序,请注意我必须将解析从 container.Resolve&lt;CustomerService&gt;(); 更改为 container.Resolve&lt;ICustomerProcessingUnit&gt;(); 否则会引发以下异常:

未处理的异常:Autofac.Core.Registration.ComponentNotRegisteredException: 请求的服务“ConsoleApplication7.CustomerService”尚未注册 红色的。为了避免这个异常,要么注册一个组件来提供服务 ,使用 IsRegistered() 检查服务注册,或使用 ResolveOptiona l() 方法来解决可选的依赖关系。

此代码虽然有效,但我怀疑您还有其他未详细说明的事情。

class Program
{
    static void Main(string[] args)
    {
        var builder = new ContainerBuilder();

        builder.RegisterType<SendService>().As<ISendService>();

        builder.RegisterType<CustomerService>()
            .As<ICustomerProcessingUnit>()
            .WithParameter("myUrl", AppSettings.Default.MyUrl);

        var container = builder.Build();

        var customerService = container.Resolve<ICustomerProcessingUnit>();
    }
}

public class SendService : ISendService
{
}

public interface ISendService
{
}

public interface ICustomerProcessingUnit
{
    Task ProcessAsync();
}

public abstract class CustomerProcessingUnitBase : ICustomerProcessingUnit
{
    public abstract Task ProcessAsync();

    public void Process()
    {
        this.ProcessAsync().Wait();
    }
}

public class CustomerService : CustomerProcessingUnitBase
{
    private string myUrl;
    private readonly ISendService sendService;

    public CustomerService(ISendService sendService, string myUrl)
    {
        this.sendService = sendService;
        this.myUrl = myUrl;
    }

    public override Task ProcessAsync()
    {
        throw new NotImplementedException();
    }
}

【讨论】:

  • 你跟我一样。但是当我在注册代码中这样做时: .WithParameter(new TypedParameter(typeof(string), MyUrlValue));那种工作!
  • 哦,这不再好笑了。正如我在解决后所说的那样,我得到了 customerService 实例,但是当我将此实例传递给其他方法时,我突然又得到了以前的异常。但我可以调试 .Resolve 确实注入了我的字符串 url。我们大量使用 AutoFac 可能是模块的问题。得和我的同事谈谈,和他一起调试。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-04-09
  • 1970-01-01
  • 2013-04-22
  • 1970-01-01
相关资源
最近更新 更多