我有一个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
,所以我似乎唯一的选择就是在我的自定义ServiceLocator
中使用ErrorLog
,如果可能的话,我希望避免使用{。}}。 p>
ELMAH中是否有更好的可用于注射的钩子?
答案 0 :(得分:13)
ELMAH中的服务位置/倾向注入扩展点是ServiceCenter.Current
属性,您可以在其中为委托提供以下签名:
public delegate IServiceProvider ServiceProviderQueryHandler(object context);
ELMAH将使用System.IServiceProvider
返回的ServiceCenter.Current
来解析ErrorLog
次要问题。
所以你需要做3件事来用Ninject(或任何DI容器)来设置它
System.IServiceProvider
实现,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;
}
注意:在ServiceProviderQueryHandler
代表中,您可以获得当前HttpContext
,然后您就可以微调您的权宜之计。
您还应注意,使用此方法,您将无法在配置文件中配置ErrorLog
。
ELMAH将始终使用容器中已解析的实例,因为内置的ServiceContainer
会读取您使用自定义逻辑覆盖的配置文件。