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}