Um übersetzbare Meldungen für Anwendungsprotokolle und/oder für Benutzer im Backend-Code (z.B. Hintergrundprozesse oder ORM-Events) zu erzeugen gibt es die Klassen TranslatableException und TranslatableMessage. Beiden gemein ist, dass die Übersetzung nachgelagert erfolgt. Dieselbe Meldung kann dadurch in verschiedenen Sprachen an verschiedene Kanäle ausgegeben werden. Z.B. bei einer Massenoperation in der Benutzersprache an den Anwender, in der Sprache für Anwendungsprotokolle in selbige und ggf. in Englisch in das Server-Log.

TranslatableException

Wird eine TranslatableException geworfen, wird diese im allgemeinen dem Benutzer als Fehler angezeigt oder bei Hintergrundprozessen ins Protokoll geschrieben. BA geht davon aus, dass es sich um eine für den Benutzer gedachte Meldung handelt, die nicht weiter angereichert oder verändert werden soll.
Andere Exceptions werden von BA als unerwartete Ausnahmen behandelt, und ggf. noch mit technischen Kontextinformationen, wie z.B. dem ORM-Event, in dem sie aufgetreten sind, angereichert. Typischerweise ergibt sich daraus kein besonders Endkundentauglicher Fehlertext.

Optional kann einer TranslatableException auch ein Schweregrad mitgegeben werden. Diese beeinflusst das Log-Level bzw. die Farbe des Toasters. Das hat aber keinen Einfluss auf die Ablaufsteuerung; es bleibt wie jede andere Exception ein Abbruch der Transaktion.

TranslatableMessage

Das ist im Prinzip dasselbe, aber eben ohne Exception. Diese Klasse eignet sich vor allem im Kontext von Anwendungsprotokollen in Hintergrundprozessen. Sie kann direkt zu einem Anwendungsprotokoll hinzugefügt werden: Logger.AddEvent(translatableMessage)
Die Angabe des Schweregrades ist hier Pflicht. Zum einfacheren Erstellen gibt es statische Fabrikmethoden, z.B.: TranslatableMessage.Info(…)

Man kann auch mehrere Meldungen mit TranslatableCompoundMessage zu einem Meldungstext zusammenfassen. Dadurch ist es möglich, mehrere, Meldungstexte mit individuellen Parametern zusammenzufassen, ohne auf die Nachtägliche Übersetzbarkeit verzichten zu müssen.

Beispiel

var msg = new TranslatableCompoundMessage { Delimiter = "\n" };
foreach ((EnumStatus status, int anzahl, DateTime von DateTime bis) in verarbeitetNachStatus)
    if (anzahl != 0)
        // "{0:N0} Datensätze im Status '{ 1 }' im Zeitraum {2:D} bis {3:D} verarbeitet."
        msg.Add(TranslatableMessage.Success("49FB98BF-A18D-4F44-BD7D-BDC14DD6F62A", anzahl, status, von, bis));
if (failed != 0)
    // "{0:N0} Datensätze fehlgeschlagen."
    msg.Add(TranslatableMessage.Warning("43B4AB04-3E0E-44EE-AFBB-296A6BF78FA5", failed));
Logger.AddEvent(msg);

Dabei könnte z.B. ein solcher Text heraus kommen:

2.738 Datensätze im Status 'versendet' im Zeitraum Montag, 15. Juni 2009 bis Mittwoch, 17. Juni 2009 verarbeitet.
24 Datensätze im Status 'in Arbeit' im Zeitraum Mittwoch, 17. Juni 2009 bis Donnerstag, 18. Juni 2009 verarbeitet.
2 Datensätze fehlgeschlagen.

bzw.

Processed 2,738 records in state 'sent' in the range Monday, June 15, 2009 to Wednesday, June 17, 2009.
Processed 24 records in state 'in progress' in the range Wednesday, June 17, 2009 to Thursday, June 18, 2009.
2 records failed.

Die Nachgelagerte Übersetzung berücksichtigt jetzt, dass die die Parameter mehrfach im Gesamttext vorkommen und immer an die korrekten Werte gebunden werden. Das wäre anders nicht möglich.

Als Bonus-Feature hat die zusammengesetzte Meldung jetzt den Schweregrad “Warnung” (gelb), weil mindestens eine solche dabei ist. Ohne die letzte Zeile wäre es “Success” (grün).