Autofac : ComponentNotRegisteredException after web site restart

Chris McKelt picture Chris McKelt · Apr 1, 2013 · Viewed 10k times · Source

I have a weird error. My site works after I upload a DLL to the bin folder.

However after I leave it for a while (or trigger a web site restart from my shared host control panel)

I get the following error

The requested service 'Nop.Core.Data.DataSettings' has not been registered. To avoid  this exception, either register a component to provide the service, check for service registration using IsRegistered(), or use the ResolveOptional() method to resolve an optional dependency.


[ComponentNotRegisteredException: The requested service 'Nop.Core.Data.DataSettings'  has not been registered. To avoid this exception, either register a component to provide the service, check for service registration using IsRegistered(), or use the ResolveOptional() method to resolve an optional dependency.]
   Autofac.ResolutionExtensions.ResolveService(IComponentContext context, Service service, IEnumerable`1 parameters) +231
   Autofac.ResolutionExtensions.Resolve(IComponentContext context, IEnumerable`1 parameters) +118
   Autofac.ResolutionExtensions.Resolve(IComponentContext context) +75
   Nop.Core.Infrastructure.DependencyManagement.ContainerManager.Resolve(String key) +156
   Nop.Core.Infrastructure.NopEngine.Resolve() +110
   Nop.Data.EfStartUpTask.Execute() +94
   Nop.Core.Infrastructure.NopEngine.RunStartupTasks() +806
   Nop.Core.Infrastructure.NopEngine.Initialize(NopConfig config) +90
   Nop.Web.MvcApplication.Application_Start() +494[/i]

Anyone have any idea on how on how to fix this?

Thanks

Answer

Travis Illig picture Travis Illig · Apr 1, 2013

It looks like app restart is causing something to want to resolve a type that isn't registered. The stack trace shows that some sort of startup task is running and that task is trying to resolve the type Nop.Core.Data.DataSettings.

First, try to find where the Nop.Core.Data.DataSettings type is registered with Autofac. You should see, somewhere in your code, a line that looks something like...

builder.RegisterType<DataSettings>();

That is, the DataSettings type should be getting registered with an Autofac.ContainerBuilder. If that line doesn't exist anywhere, you need to add it so the type is registered. Autofac doesn't just "automatically" resolve types that aren't registered. (Alternatively, you could register the AnyConcreteTypeNotAlreadyRegisteredSource with Autofac, but that's usually overkill.)

If you can't find that line, you need to add it. Where is dependent on your application, but you should see a block of other places where things are getting registered with Autofac - that's probably a good spot to put this, too.

If DataSettings is already getting registered, then it means your application restart doesn't always execute startup actions in the same order, or maybe doesn't even execute the same startup actions all the time. This sort of thing can happen if you have code that runs at app startup (like in an HttpModule) that doesn't handle multiple worker processes properly or isn't handling threading properly.

Another potential (but not probable) case is that you have two Autofac containers running in your application and while DataSettings is in one of them, it's not in the other. This is really edge case stuff but it's possible.

Next, look at all the code along the stack trace. Figure out what's trying to resolve the DataSettings object. It may not be getting resolved directly; it may be a constructor dependency on something else that's getting resolved. You're going to have to spelunk into the code to figure it out.

In any case, this looks like an app startup problem rather than an Autofac problem. Autofac doesn't just "lose" registrations - if it's complaining that you're trying to resolve something that isn't registered... then it isn't registered.

The exception message is telling you everything you need to know to debug it - where the resolution is occurring, what it's looking for... you need to crack open your app code, look at the actual execution path shown in the stack trace, and see what's getting resolved, when, and why so you can figure out how to fix it.