2012-10-16 6 views
5

Ich habe eine ELMAH benutzerdefinierte ErrorLog, die einen EF-Code-First Kontext verwendet, die Fehler zu speichern: -Wie kann ich Abhängigkeiten in einen benutzerdefinierten ELMAH-ErrorLog injizieren?

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. 

} 

Die ErrorLog in der web.config verdrahtet sind: -

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

I‘ Ich verwende Ninject bereits anderweitig im Projekt. Ich möchte MyContext injizieren, so dass die ErrorLog nicht seine eigene Abhängigkeit instanziiert, aber ich habe kein Glück, einen Haken in der Dokumentation zu finden. ELMAH scheint die ErrorLog intern zu instantiieren, so dass die einzige Option, die ich zu haben scheint, eine ServiceLocator in meiner eigenen ErrorLog ist, die ich wenn möglich vermeiden möchte.

Gibt es in ELMAH bessere Haken, die ich zum Einspritzen verwenden kann?

Antwort

13

Der Service-Standort/Depdency Injektion Erweiterungspunkt in ELMAH ist die ServiceCenter.Current Eigenschaft, wo Sie einen Delegaten mit der folgenden Signatur zur Verfügung stellen können:

public delegate IServiceProvider ServiceProviderQueryHandler(object context); 

ELMAH wird die System.IServiceProvider vom ServiceCenter.Current zurück verwenden, um die ErrorLog isntances zu lösen .

Sie müssen also drei Dinge Setup mit Ninject, es zu tun (oder einem DI-Container)

  1. Erstellen Sie Ihre eigenen System.IServiceProvider Implementierung mit Ninject die IKernel Schnittstelle bereits ab von System.IServiceProvider leitet, so dass es getan hat.
  2. Sie müssen Ihren EntityFrameworkElmahErrorLog in Ihrem Container als ErrorLog Implementierung registrieren, da ELMAH versuchen wird, eine Instanz von ErrorLog aufzulösen.
  3. Bieten Sie Ihren Delegierten ServiceCenter.Current

Sie müssen also so etwas wie die folgenden in Ihrem RegisterServices Methode:

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

Hinweis: in der ServiceProviderQueryHandler delegieren Sie die aktuelle HttpContext bekommen und damit können Sie Feinabstimmung, wie Ihre Probleme gelöst werden.

Sie sollten auch beachten, dass mit diesem Ansatz verlieren Sie die Möglichkeit, Ihre ErrorLog in Ihrer Konfigurationsdatei zu konfigurieren.

ELMAH wird immer die aufgelöste Instanz aus Ihrem Container verwenden, da das eingebaute die Konfigurationsdatei liest, was Sie mit Ihrer benutzerdefinierten Logik überschreiben.

+0

Perfekt, danke! –