I have an ELMAH custom ErrorLog that uses an EF Code-First context to store the errors:-
class EntityFrameworkElmahErrorLog
{
public EntityFrameworkElmahErrorLog(IDictionary config) : this() { }
public override ErrorLogEntry GetError(string id)
{
using (var context = new MyContext())
{
var intId = Int64.Parse(id, CultureInfo.InvariantCulture);
var item = context.ErrorLog.Single(x => x.Id == intId);
return new ErrorLogEntry(this, id, ErrorXml.DecodeString(item.Details));
}
}
// etc.
}
The ErrorLog is wired up in the web.config:-
<errorLog type="MyProject.EntityFrameworkErrorLog, MyProject" />
I'm already using Ninject elsewhere in the project. I'd like to inject MyContext
so that the ErrorLog
isn't instantiating its own dependency, but I'm not having any luck finding a hook in the documentation. ELMAH appears to be instantiating the ErrorLog
internally, so the only option I seem to have is using a ServiceLocator
inside my custom ErrorLog
, which I'd like to avoid if possible.
Are there any better hooks available in ELMAH that I can use to inject ?
The Service location/Depdency injection extension point in ELMAH is the ServiceCenter.Current
property where you can provide a delegate with the following signature:
public delegate IServiceProvider ServiceProviderQueryHandler(object context);
ELMAH will use the System.IServiceProvider
returned by the ServiceCenter.Current
to resolve the ErrorLog
isntances.
So you need to do 3 things to setup it with Ninject (or any DI container)
System.IServiceProvider
implementation with Ninject the IKernel
interface already derives from from System.IServiceProvider
, so it's done.EntityFrameworkElmahErrorLog
in your container as an ErrorLog
implemenation, because ELMAH will try to resolve an instance of ErrorLog
.ServiceCenter.Current
So you need something like the following in your RegisterServices
method:
private static void RegisterServices(IKernel kernel)
{
kernel.Bind<ErrorLog>().To<EntityFrameworkElmahErrorLog>();
ServiceCenter.Current = (httpContext) => kernel;
}
Note: in in the ServiceProviderQueryHandler
delegate you get the current HttpContext
and with that you can fine tune how your expediencies are resolved.
You should also note that with this approach you will lose the ability to configure your ErrorLog
in your config file.
ELMAH will always use the resolved instance from your container, because the built in ServiceContainer
reads the config file what you override with your custom logic.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With