我有一个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容器)来设置它
System.IServiceProvider使用Ninject 创建自己的实现,IKernel接口已经从中派生出来System.IServiceProvider,所以就完成了.EntityFrameworkElmahErrorLog在容器中注册您的ErrorLog实现,因为ELMAH将尝试解析您的实例ErrorLog.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读取您使用自定义逻辑覆盖的配置文件.