.NET, architecture, C#, CSharp, Programming

Wysyłanie maili z wykorzystaniem Handlebars

Niedawno musiałem zmierzyć się z budowaniem maili. Starym sposobem projektu było robienie tego w każdym miejscu, które wysyłało maila, tzn każdy projekt był właścicielem szablonu, a sam szablon był zdeployowany z kodem i wypełniany przez kod źródłowy string.Replace albo string.Format. Brzmi trochę creepy, prawda? To co z tym zrobić, żeby było uniwersalnie i bez jawnych operacji na stringach, a także z możliwością wypełniania list? Na takie problemy – Handlebars. Biblioteka pozwala wypełnić szablon danymi, używać pętli, wyrażeń warunkowych itd, zatem jest całkiem “sprytna” – podajemy szablon i model (obiekt z danymi), który ma go wypełnić i volia! No prawie 😉 bo okazuje się, że jak jakiegoś pola nie ma w modelu, to się o tym dowiemy w trakcie testów, ponieważ pole nie będzie wypełnione (pozostanie puste).

W jaki sposób dorzucenie Handlebars rozwiązało problem? Serwis, na podstawie przesłanego modelu, który zawiera m.in. object Content przekazywany do Handlebars, wypełnia wskazany szablon (nazwa szablonu to część modelu danych zdefiniowanego w serwisie, dystrybuowanego jako nuget), odczytywany ze współdzielonego storage, zatem jakiekolwiek dodanie nowego maila to tylko upload szablonu i budowa modelu danych, który go wypełni.

Trochę kodu

W praktyce samo wdrożenie Handelbars można ograniczyć do dodania 2 nugetów:

  • Handlebars.Net
  • Handlebars.Net.Extension.Json

Druga z paczek jest niezbędna, jeśli serializujecie dane System.Text.Json. Domyślną serializacją jest Newtonsoft.JSON.

Aby zmienić serializator (deserializację) w trakcie konfiguracji należy dodać Handlebars.Configuration.UseJson();

Jeśli chodzi o DI/IoC, to możemy stworzyć w trakcie rejestracji zależności Handlebars.Create i wstrzyknąć IHandlebars.

Samo dalsze przetworzenie to już tylko 2 linijki:

var compiled = _handlebars.Compile(template);
var filledTemplate = compiled(data);

W efekcie w zmiennej filledTemplate dostaniemy wypełniony szablon i teraz możemy go przekazać dalej, do wysłania do odbiorcy końcowego.

Rozszerzenia

Niektóre formatowania np. pieniędzy wykonujemy zawsze w ten sam sposób (tzn z 2 miejscami po przecinku), ale nie są wbudowane w Handlebars. Dlatego konieczne jest stworzenie własnego rozszerzenia. W moim przypadku, było to proste, ze względu na to, że muszę wspierać tylko 1 walutę w 1 kraju, więc zawsze mogę sformatować tak samo. Przykład, jak napisać rozszerzenie formatujące, znajduje się na stronie Handlebars.NET. I uważajacie – decimal? to nie to samo co decimal :-).

Testy jednostkowe

Tu jest smutna refleksja – samego generowania nie da się zamockować (przynajmniej prosto). Próbowałem z tym powalczyć i skończyłem z testami integracyjnymi, podobnie jak to wygląda na stronie projektu.

Przydatne linki

Projekt Handlebars.NET: https://github.com/Handlebars-Net/Handlebars.Net

Strona projektu Handlebars: https://handlebarsjs.com

Leave a Reply

Your email address will not be published. Required fields are marked *