2016-08-04 36 views
2

BEARBEITEN, zuerst lesen: Es ist nicht die using-Anweisung essen meine ApplicationException, es ist die DependencyResolver, die ich in meinem echten Code verwendet wurde. Ich habe nicht einmal daran gedacht, zuerst nach ihnen zu suchen, aber tatsächlich, wenn ich versuche, die Klasse direkt zu instantiieren (genauso wie ich es in meinem vereinfachten Beispielcode getan habe), funktioniert es wie erwartet. Es verhält sich nur so, wie ich es unten dokumentiere, wenn ich den DependencyResolver in der using-Anweisung verwende. Ich habe einfach nicht daran gedacht, dies in meiner Frage zu erwähnen, weil ich es übersehen habe. Ich verwende einen Unity-Container, nur zur Info. Ich werde dies aktualisieren, während ich es durcharbeite und lösche es vielleicht einfach.Wie kann ich automatisch eine ApplicationException auslösen, wenn eine Datenbankverbindung in einer using-Anweisung fehlschlägt, die eine DbContext-Ressource instanziiert?

Update 2: Ok, so stellt sich heraus, dass das Zurückgeben einer Null-Ressource, wenn ein Service-Standort eine Ausnahme auslöst, ein völlig normales und erwartetes Verhalten in MVC ist. Ich bin völlig blind für die Tatsache geworden, dass ich die Abhängigkeitsinjektion verwendete, als ich das erste Mal auf dieses Verhalten stieß und mich verwirrte. Also lasse ich diese Frage offen, für den Fall, dass sich jemand in einer ähnlichen Situation befindet. Sie können keine Ausnahme auslösen, wenn Sie eine Ressource erstellen, die mit dem DependencyResolver-Service-Locator aufgelöst wird! Es schluckt die Ausnahme und gibt eine Null-Ressource zurück!

Auch für den Fall, dass jemand sich fragt, was ich angesichts dieser neuen Informationen geändert habe: Ich habe einfach meine Logik zum Überprüfen von Datenbanken/Exceptions in einige Schlüsselmethoden innerhalb des Repository verschoben und nicht innerhalb des Konstruktors. Ich habe auch aufgehört, Unity zu verwenden und zu Ninject gewechselt, und ging von einem Service-Locator-Muster zu meinem Container in eine Singleton-Klasse gewickelt, aber das hatte nichts mit dem Problem zu tun, das zu diesem Thread führte und war mehr von nur einem Stil Wahl.

End-Bearbeitungen

können also sagen, dass ich eine Art von Klasse, die auf eine Datenbank zugreift, so ...

public class Foo : IDisposable { 

    private DbContext db = new FooDbContext(); 

    public DoSomething(){ 
     // do something with the FooDbContext... 
    } 

    // Dispose is implemented here as well... 

} 

Wenn ich diese Klasse zu verwenden, ich auf sie wie diese ...

using (Foo foo = new Foo()){ 
    foo.DoSomething(); 
} 

Also, was ich erreichen wollen ist, dass, wenn eine Foo-Klasse ist const Wenn der zugrunde liegende DbContext keine Verbindung herstellen kann, wird eine ApplicationException ausgelöst.

So füge ich den folgenden Konstruktor der Klasse Foo ...

public Foo() { 
    try 
     { 
      db.Database.Connection.Open(); 
     } 
     catch 
     { 
      throw new ApplicationException("Database is not currently available. Try again later."); 
     } 
} 

aber hier ist das Problem, zu diesem Code zurück ...

using (Foo foo = new Foo()){ 
    foo.DoSomething(); 
} 

Wenn die using-Anweisung ausgeführt wird, Während die Datenbank nicht verfügbar ist (und ich dies durch Debuggen bestätigt habe), wird eine ApplicationException ausgelöst, wenn Foo erstellt wird, jedoch wird ApplicationException ignoriert und die DoSomething-Methode wird trotzdem aufgerufen. An diesem Punkt bekomme ich eine NullReferenceException statt meiner gewünschten ApplicationException, weil foo null ist.

Was ist mit meiner ApplicationException passiert? Warum wird es ignoriert? Und was kann ich tun, um sicherzustellen, dass die ApplicationException platzt?

Ich möchte nicht wirklich die ApplicationException behandeln. Für einige Kontexte ist dies eine ASP.NET MVC-Anwendung.Ich möchte, dass die ApplicationException unbehandelt bleibt und dass die benutzerdefinierte Fehlerseite, die ich eingerichtet habe, die in der ApplicationException enthaltene Nachricht für den Benutzer anzeigt.

+0

So Ihre Abhängigkeitsauflöser zeigen, ist es, dass die eine ist die Ausnahme zu essen. – CodeCaster

+0

Sorry, ich habe vergessen, dieses Ding aktualisiert zu halten. Wie ich bereits in meinem Beitrag erwähnt habe, war dies definitiv auf die Abhängigkeitsinjektion zurückzuführen und hatte nichts mit der using-Anweisung zu tun. Ich habe ein Service-Locator-Muster mit einem Unity-Container verwendet, der beim Dependency-Resolver registriert ist. Wie sich herausstellt, ist das Zurückgeben einer Null-Ressource ein erwartetes Verhalten, zumindest bei MVC. Wie auch immer, ich habe seitdem aufgehört, das Service-Locator-Muster zu verwenden, und wechselte von Unity zu einem Ninject-Container. Ich werfe jetzt die Ausnahme innerhalb der Methoden anstatt auf dem Aufbau des Lagers. – spoonraker

Antwort

1

Ich denke, dass Ihr Problem, ohne in db und Verbindung Details gehen ist etwas wegen der Verwendung von Block, der using-Block schlucken die Ausnahme im Konstruktor geschehen.

http://www.digitallycreated.net/Blog/51/c%23-using-blocks-can-swallow-exceptions

https://msdn.microsoft.com/en-us/library/aa355056.aspx

+0

Es ist nicht wirklich die using-Anweisung, die die Ausnahme verschluckt. Ich habe das selbst getestet. Ich habe vergessen, in meiner ursprünglichen Frage zu erwähnen, dass ich ein Service-Locator-Muster für die Abhängigkeitsinjektion verwendet habe, und es war tatsächlich der Service-Locator, der in der Ausnahme schluckt. Und es stellt sich heraus, dass dies auch kein unerwartetes Verhalten ist, sondern dass es zumindest bei MVC sehr bewusst ist. Eine NULL-Ressource wird vom Dependency-Resolver zurückgegeben und alle Ausnahmen werden ignoriert, damit MVC nicht vollständig unterbrochen wird. – spoonraker