In an ASP.NET Web API project, if you are using Simple Injector for dependency injection, it will register all controllers with this line of code:
container.RegisterWebApiControllers(
System.Web.Http.GlobalConfiguration.Configuration);
If you have Elmah logger in the same project, to access the logger you just use http://yourapp.com/elmah as shown here.
The problem is that Simple Injector thinks elmah is a controller and produces this error:
No registration for type ElmahController could be found.
I thought to configure Simple Injector to avoid construction if the type has elmah but I cannot figure out how.
What do I need to do to fix this?
Here is the full error:
No registration for type ElmahController could be found. Make sure ElmahController is registered, for instance by calling 'Container.Register();' during the registration phase. An implicit registration could not be made because Container.Options.ResolveUnregisteredConcreteTypes is set to 'false', which is now the default setting in v5. This disallows the container to construct this unregistered concrete type. For more information on why resolving unregistered concrete types is now disallowed by default, and what possible fixes you can apply, see https://simpleinjector.org/ructd. Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.
Exception Details: SimpleInjector.ActivationException: No registration for type ElmahController could be found. Make sure ElmahController is registered, for instance by calling 'Container.Register();' during the registration phase. An implicit registration could not be made because Container.Options.ResolveUnregisteredConcreteTypes is set to 'false', which is now the default setting in v5. This disallows the container to construct this unregistered concrete type. For more information on why resolving unregistered concrete types is now disallowed by default, and what possible fixes you can apply, see https://simpleinjector.org/ructd.
Source Error:
An unhandled exception was generated during the execution of the current web request. Information regarding the origin and location of the exception can be identified using the exception stack trace below.
Stack Trace:
[ActivationException: No registration for type ElmahController could be found. Make sure ElmahController is registered, for instance by calling 'Container.Register();' during the registration phase. An implicit registration could not be made because Container.Options.ResolveUnregisteredConcreteTypes is set to 'false', which is now the default setting in v5. This disallows the container to construct this unregistered concrete type. For more information on why resolving unregistered concrete types is now disallowed by default, and what possible fixes you can apply, see https://simpleinjector.org/ructd. ] SimpleInjector.Container.ThrowNotConstructableException(Type concreteType) +138 SimpleInjector.Container.ThrowMissingInstanceProducerException(Type type) +88 SimpleInjector.Container.GetInstanceForRootType(Type serviceType) +186 SimpleInjector.Container.GetInstance(Type serviceType) +82 System.Web.Mvc.DefaultControllerActivator.Create(RequestContext requestContext, Type controllerType) +64
[InvalidOperationException: An error occurred when trying to create a controller of type 'Elmah.Mvc.ElmahController'. Make sure that the controller has a parameterless public constructor.] System.Web.Mvc.DefaultControllerActivator.Create(RequestContext requestContext, Type controllerType) +245 System.Web.Mvc.MvcHandler.ProcessRequestInit(HttpContextBase httpContext, IController& controller, IControllerFactory& factory) +267 System.Web.Mvc.MvcHandler.BeginProcessRequest(HttpContextBase httpContext, AsyncCallback callback, Object state) +77 System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +970 System.Web.HttpApplication.ExecuteStepImpl(IExecutionStep step) +75 System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +158
Ok I think I figured it out.
Some Notes
Since I have configured the container's lifestyle like this:
I cannot use
LifeStyle.Scopedwhen registering theElmahController. The 2 other options areLifeStyle.SingletonandLifeStyle.Transient. We don't wantLifeStyle.Singletonbecause numerous instances are needed, thus we have one option left which isLifeStyle.Transcient.Solution
You need to register it with Simple Injector:
The line above will result in a different error:
To get rid of that error, I first checked to see if the
Disposemethod forElmahControllerhas anything useful. It turns out it simply derives fromSystem.Web.Mvc.Controllerand here is theDisposemethod:Since it does nothing useful, it is fine if it is not called. Thus the following code is enough: