An item with the same key has already been added w

2019-04-13 01:07发布

This is really odd. Have an MVC 5 application using Autofac 3.3 that throws the An item with the same key has already been added error when I add a new controller that doesn't have specific constructor signatures.

How do I go about debugging this?

If the constructor looks like the following then when I navigate to the url for that controller it loads fine:

public class ProductController : Controller
{
    private readonly IServiceManager _serviceManager;

    public ProductController(IServiceManager serviceManager)
    {
        _serviceManager = serviceManager;
    }
 }

But if I add a new controller with no constructor, a parameter-less constructor, or various other signatures and navigate to that specific url it explodes:

public class QuestionController : Controller
{
    // explodes
    public QuestionController()
    {
    }
    // explodes
    public QuestionController(DbContext ctx)
    {
    }
    // loads fine
    public QuestionController(IServiceManager serviceManager)
    {
    }
    // loads fine
    public QuestionController(AnonymousIdentityHandler handler)
    {
    }
}

I'm doing this in my registration for Autofac:

 builder.RegisterControllers(Assembly.GetExecutingAssembly()).PropertiesAutowired();

Stack Trace:

[ArgumentException: An item with the same key has already been added.]
   System.ThrowHelper.ThrowArgumentException(ExceptionResource resource) +52
   System.Collections.Generic.Dictionary`2.Insert(TKey key, TValue value, Boolean add) +10933453
   System.Collections.Generic.Dictionary`2.Add(TKey key, TValue value) +23
   Autofac.Core.Lifetime.LifetimeScope.GetOrCreateAndShare(Guid id, Func`1 creator) +161
   Autofac.Core.Resolving.InstanceLookup.Execute() +132
   Autofac.Core.Resolving.ResolveOperation.GetOrCreateInstance(ISharingLifetimeScope currentOperationScope, IComponentRegistration registration, IEnumerable`1 parameters) +133
   Autofac.Core.Resolving.InstanceLookup.ResolveComponent(IComponentRegistration registration, IEnumerable`1 parameters) +24
   Autofac.Core.Registration.<>c__DisplayClass8.<RegistrationsFor>b__3(IComponentContext c, IEnumerable`1 p) +19
   Autofac.Core.Activators.Delegate.DelegateActivator.ActivateInstance(IComponentContext context, IEnumerable`1 parameters) +32
   Autofac.Core.Resolving.InstanceLookup.Activate(IEnumerable`1 parameters) +48
   Autofac.Core.Resolving.InstanceLookup.Execute() +48
   Autofac.Core.Resolving.ResolveOperation.GetOrCreateInstance(ISharingLifetimeScope currentOperationScope, IComponentRegistration registration, IEnumerable`1 parameters) +133
   Autofac.Core.Resolving.InstanceLookup.ResolveComponent(IComponentRegistration registration, IEnumerable`1 parameters) +24
   Autofac.ResolutionExtensions.TryResolveService(IComponentContext context, Service service, IEnumerable`1 parameters, Object& instance) +74
   Autofac.ResolutionExtensions.ResolveService(IComponentContext context, Service service, IEnumerable`1 parameters) +53
   Autofac.Core.Activators.Reflection.AutowiringPropertyInjector.InjectProperties(IComponentContext context, Object instance, Boolean overrideSetValues) +594
   Autofac.Builder.<>c__DisplayClassd.<PropertiesAutowired>b__c(Object s, ActivatingEventArgs`1 e) +32
   Autofac.Core.Registration.ComponentRegistration.RaiseActivating(IComponentContext context, IEnumerable`1 parameters, Object& instance) +73
   Autofac.Core.Resolving.InstanceLookup.Activate(IEnumerable`1 parameters) +128
   Autofac.Core.Resolving.InstanceLookup.Execute() +48
   Autofac.Core.Resolving.ResolveOperation.GetOrCreateInstance(ISharingLifetimeScope currentOperationScope, IComponentRegistration registration, IEnumerable`1 parameters) +133
   Autofac.Core.Resolving.InstanceLookup.ResolveComponent(IComponentRegistration registration, IEnumerable`1 parameters) +24
   Autofac.Core.Registration.<>c__DisplayClass8.<RegistrationsFor>b__3(IComponentContext c, IEnumerable`1 p) +19
   Autofac.Core.Activators.Delegate.DelegateActivator.ActivateInstance(IComponentContext context, IEnumerable`1 parameters) +32
   Autofac.Core.Resolving.InstanceLookup.Activate(IEnumerable`1 parameters) +48
   Autofac.Core.Resolving.InstanceLookup.Execute() +48
   Autofac.Core.Resolving.ResolveOperation.GetOrCreateInstance(ISharingLifetimeScope currentOperationScope, IComponentRegistration registration, IEnumerable`1 parameters) +133
   Autofac.Core.Resolving.ResolveOperation.Execute(IComponentRegistration registration, IEnumerable`1 parameters) +44

Autofac registrations:

builder.RegisterType<WebApiContext>().As<DbContext>().Named<DbContext>("WebApiContext").InstancePerHttpRequest();
builder.RegisterType<MainContext>().As<DbContext>().Named<DbContext>("MainContext").InstancePerHttpRequest();

builder.RegisterType<ServiceManager>().As<IServiceManager>().Named<IServiceManager>("OneTime").InstancePerDependency();
builder.RegisterType<ServiceManager>().As<IServiceManager>().InstancePerHttpRequest();

builder.RegisterType<SecurityConfig>().AsSelf().PropertiesAutowired().InstancePerDependency();

builder.RegisterType<apiController>().WithParameter(ResolvedParameter.ForNamed<DbContext>("WebApiContext")).InstancePerHttpRequest();

builder.RegisterWebApiFilterProvider(GlobalConfiguration.Configuration);

// controllers
builder.RegisterControllers(Assembly.GetExecutingAssembly()).PropertiesAutowired();
// allows injection into custom WebViewPage
builder.RegisterSource(new ViewRegistrationSource());

// various
builder.RegisterType<ApplicationUser>().AsSelf().InstancePerHttpRequest();
builder.RegisterType<AnonymousIdentityHandler>().AsSelf().InstancePerHttpRequest();
builder.RegisterType<ServiceBase>().AsSelf().InstancePerHttpRequest().PropertiesAutowired();

// register all entity repositories
builder.RegisterGeneric(typeof(EntityRepository<>)).As(typeof(IRepository<>)).InstancePerHttpRequest();

// services
builder.RegisterAssemblyTypes(typeof(Product).Assembly)
    .Where(t => t.Name.EndsWith("Service"))
    .InstancePerHttpRequest().PropertiesAutowired(PropertyWiringOptions.AllowCircularDependencies);

// paging stuff
builder.RegisterType<PagedProduct>().As<IPagedProduct<ProductForSearchResult>>().InstancePerDependency();
builder.RegisterType<Pager>().As<IPager>().InstancePerDependency();
builder.RegisterGeneric(typeof(PagedList<>)).InstancePerDependency();

// mvc action method injection.
builder.RegisterType<ExtensibleActionInvoker>().As<IActionInvoker>();

// http abstractions
builder.RegisterModule(new AutofacWebTypesModule());

IContainer container = builder.Build();

GlobalConfiguration.Configuration.DependencyResolver = new AutofacWebApiDependencyResolver(container);

DependencyResolver.SetResolver(new AutofacDependencyResolver(container));

return container;

Update 1

I was able to step into the Autofac code and discovered that Autofac is attempting to add the same key twice during GetOrCreateAndShare(Guid id, Func<object> creator) call. I'm not sure how to fix this though. I only have one call to register that type. Perhaps a threading bug with autofac?

+       this    {Autofac.Core.Lifetime.LifetimeScope}   Autofac.Core.Lifetime.LifetimeScope
+       id  {3dc68c6e-60f2-4318-8975-6eb68ce82f3f}  System.Guid
+       creator {Method = {System.Object <Execute>b__0()}}  System.Func<object>
+       obj2    {SR.Data.Security.ApplicationUser}  object {SR.Data.Security.ApplicationUser}

0条回答
登录 后发表回答