如何将依赖项注入ELMAH自定义ErrorLog?

Iai*_*way 5 c# elmah ninject

我有一个ELMAH自定义ErrorLog,它使用EF Code-First上下文来存储错误: -

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.

}
Run Code Online (Sandbox Code Playgroud)

ErrorLog已在web.config中连接: -

<errorLog type="MyProject.EntityFrameworkErrorLog, MyProject" />
Run Code Online (Sandbox Code Playgroud)

我已经在项目的其他地方使用了Ninject.我想注入,MyContext以便ErrorLog没有实例化自己的依赖,但我没有运气在文档中找到钩子.ELMAH似乎是在ErrorLog内部实例化,所以我似乎唯一的选择是使用ServiceLocator我的自定义内部ErrorLog,如果可能的话我想避免使用.

ELMAH中有哪些更好的钩子我可以用来注射?

nem*_*esv 13

ELMAH中的服务位置/ Depdency注入扩展点是ServiceCenter.Current您可以为委托提供以下签名的属性:

public delegate IServiceProvider ServiceProviderQueryHandler(object context);
Run Code Online (Sandbox Code Playgroud)

ELMAH将使用由... System.IServiceProvider返回ServiceCenter.Current来解决的ErrorLog问题.

所以你需要做3件事来用Ninject(或任何DI容器)来设置它

  1. System.IServiceProvider使用Ninject 创建自己的实现,IKernel接口已经从中派生出来System.IServiceProvider,所以就完成了.
  2. 您需要EntityFrameworkElmahErrorLog在容器中注册您的ErrorLog实现,因为ELMAH将尝试解析您的实例ErrorLog.
  3. 提供你的代表 ServiceCenter.Current

因此,您需要在RegisterServices方法中使用以下内容:

private static void RegisterServices(IKernel kernel)
{
    kernel.Bind<ErrorLog>().To<EntityFrameworkElmahErrorLog>();
    ServiceCenter.Current = (httpContext) => kernel;
}  
Run Code Online (Sandbox Code Playgroud)

注意:在ServiceProviderQueryHandler代理中,您可以获得最新信息HttpContext,然后您可以微调您的权宜之计的解决方式.

您还应注意,使用此方法,您将无法ErrorLog在配置文件中配置.

ELMAH将始终使用容器中已解析的实例,因为内置函数会ServiceContainer读取您使用自定义逻辑覆盖的配置文件.