繁体   English   中英

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

[英]How can I inject dependencies into an ELMAH custom ErrorLog?

我有一个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.

}

ErrorLog已在web.config中连接: -

<errorLog type="MyProject.EntityFrameworkErrorLog, MyProject" />

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

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

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

public delegate IServiceProvider ServiceProviderQueryHandler(object context);

ELMAH将使用ServiceCenter.Current返回的System.IServiceProvider来解析ErrorLog异常。

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

  1. 使用Ninject创建您自己的System.IServiceProvider实现, 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;
}  

注意:在ServiceProviderQueryHandler委托中,您将获得当前的HttpContext ,并且您可以通过它来微调您的权宜之计的解决方式。

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM