Making Postal send mails with Postmark

In my previous post I praised Postal for being such a simple and easy library to use for templating and sending emails from your .net app. I also briefly mentioned how it just uses the standard SMTP settings from your Web.config or App.config file for sending out the mails.

This is fine in most scenarios, but on one of our last projects we were using Postmark and gave preference to using the HTTP API instead of relying on the SMTP protocol. The main advantage of this is that HTTP tends to be far less chatty than SMTP and you can increase the throughput of your mails.

Step 1: Install Postmark .net library

From the Package Manager Console inside Visual Studio do:

Install-Package Postmark

This installs the official Postmark .net library from NuGet.

Step 2: Implement an IEmailService

An IEmailService is Postal's way to allow you to alter the behaviour of sending the email. The default implementation uses the System.Net.Mail namespace to compose a MailMessage instance and send it using the configuration that sits in your .config file.

This is what we want to change in order to start using the Postmark API, we can send emails using the following code snippet.

    MailMessage message = ...;

    var client = new PostmarkClient("<your api token goes here>");
    client.SendMessageAsync(message);

This is absolutely perfect, because the default EmailService implementation contains a method to create a MailMessage based on an Email object, so we can simply use that and pass the MailMessage to the PostmarkClient. The result is the following service:

    public class PostmarkEmailService : IEmailService
    {
        // the default implementation used to generated
        // the MailMessage objects
        private Postal.EmailService _inner;
        private PostmarkClient _client;

        public PostmarkEmailService(string token)
        {
            _inner = new EmailService();
            _client = new PostmarkClient(token);
        }

        public void Send(Email email)
        {
            var msg = CreateMailMessage(email);
            _client.SendMessageAsync(msg)
                   .Wait();
        }

        public Task SendAsync(Email email)
        {
            var msg = CreateMailMessage(email);
            return _client.SendMessageAsync(msg);
        }

        public MailMessage CreateMailMessage(Email email)
        {
            return _inner.CreateMailMessage(email);
        }
    }

Step 3: Set an instance of our service as the default one

Now that we have a service that can send Emails using the Postmark API, the only thing that remains to be done is to configure Postal the use it as IEmailService used for sending out the mails during the startup of our app.

    Email.CreateEmailService = () => new PostmarkEmailService("<your token goes here>");

Conclusion

That's it! From now on all Send calls on an Email object will use Postmark to send out the emails. Changing Postal's default send implementation is super easy, thanks to the nice NuGet package that Postmark provides and to the extensibility of Postal.

Open Source .net libraries that make your life easier

Even though people sometimes claim that open source .net is not in a healthy state and that the community too often relies on what Microsoft is providing, there do exist some awesome open source libraries out there. Over the course of the last couple of years, we've started several - often small scale - new projects at work and I've come to rely on some libraries that solve some specific problems, and they solve them well. This post is not about packages that are in NuGet's top 100 list, but about lesser known libraries that deserve some extra attention.

Are there some things they have in common? Yes!

  1. Most of them have excellent documentation, time and time again this turns out to be extremely important for any OSS project, especially go get starters on board.
  2. These libraries are not frameworks in the sense that they don't force you into any application structure or require you to inherit from class X or Y. They are just nice libraries that you can plug into your projects and they do what they promise.

So let's get into it...

Hangfire

Hangfire is a library that allows you to quickly and beautifully add background processing to your ASP.net application. It's extremely simple to setup and scheduling background work is as straightforward as it can be.

BackgroundJob.Enqueue(() => Console.WriteLine("Simple!")); 

There are several things I love about Hangfire:

  • The built-in dashboard is beautiful, clear and gives a good view of what is happening and - maybe more important - what is going wrong.

dashboard

  • There are no requirements on the method that is to be executed in the background. No class to inherit from, no attributes have to added to it, it just needs to be a public method. This allows you to structure your background jobs as you see fit.

  • While It Just Works when you add it to an ASP.net application, you're not restricted to it. You can schedule and process the jobs basically anywhere: Windows Services, Console Applications, Azure Web workers, .... If you include this in your application, you know that you will be able to take your code and split it into different components if needed. And Hangfire will still be able to do the processing.

  • It was once featured on Scott Hanselman's blog. It probably helped a lot to highlight the existence of Hangfire, but some people also quickly noted its shortcomings. It had a dependancy on System.Web even though it was architected as an OWIN component, it depended on Common.Logging and used SQL Server by default. All of these were true, but it should be noted that Hangfire's author Sergey Odinokov has been quick to address the issues. By now, Hangfire is already in a much better shape, so I have the impression that Sergey knows very well what he is doing.

Postal

Shortly after the Razor View Engine came out for ASP.net, Andrew Davey had the excellent idea to start using it to do Email templating: Postal was born. The idea is simple, your Views folder gets an extra subdirectory called Emails where you put in all your Razor Email templates and everything Razor has to offer comes for free: Layouts, strongly-typed models, Url-helpers, partials, etc. Sending an e-mail is as simple as

dynamic email = new Email("Example"); // Uses Views\Emails\Example.cshtml
email.To = "webninja@example.com";
email.FunnyLink = DB.GetRandomLolcatLink();
email.Send();

You basically create a Email object and treat it as a dynamic, you chuck some properties onto it, which you can then inside your Email template.

To: @ViewBag.To
From: lolcats@website.com
Subject: Important Message

Hello,
You wanted important web links right?
Check out this: @ViewBag.FunnyLink

<3

Of course you can use strongly-typed Models if you want to.

It respects Web.config's smtp settings and hence works perfectly with services like Mandrill or Postmark, has some nice features like image inlining, and it is built to integrate perfectly with any MVC version. Good stuff!

Formo

Whether you're in a console app, a web application or a windows service, reading from your app.config's and web.config's application settings is never a fun thing to do, especially if you want to read DateTime or int values.

Formo solves this problem very elegantly by simply exposing the settings as a dynamic object. This makes the code to read the settings much easier on the eye.

dynamic config = new Formo.Configuration();

// This simply reads the string
string apiEndPoint = config.ApiEndPoint;

// This converts the value in to an int, no 
// need to do any conversion in your code
int timeout = config.ApiTimeout<int>();

// This uses a default value of 5 if the
// configuration files contains no values
int retries = config.ApiRetries<int>(5);

If you don't like dynamic, you can even go a step further and bind the application settings to a simple POCO class.

public class Settings
{
    public string ApiEndpoint { get; set; }

    public int ApiTimeout { get; set; }
}

dynamic configuration = new FormoConfiguration();
Settings settings = configuration.Bind<Settings>();

Even though Formo's scope is very limited and even though it seems that reading configuration files will change drastically with aspnet5, I find it a very useful library which for me has reduced the friction of reading config files perfectly.

CsvHelper

When dealing with data from legacy systems, then CSV files are still commonly used as the way to export data. In the past I have used several different ways of dealing with these files: copy/paste from codeproject (yeah, I know), hand written CSV reader for specific format, etc.

Until I bumped into CsvHelper, that is. The feature that I love the most, is how you can define a CsvClassMap to populate a certain POCO class. You can then use a CsvReader to convert each row into an instance of that POCO class. That way, you don't have to think about all the nitty gritty details that can occur when you need to read CSV files. These class maps provide a lot of configuration options and I have yet to encounter a situation that CsvHelper cannot handle.

Topshelf

Writing a Windows Service is a lot harder than it should be. The logic itself is the easy part, but writing and configuring the part that creates the service on the system is just a mess. If you follow the Visual Studio Way of doing things, this mess involves

  • Creating a ServiceBase class, this contains the business logic of th Service
  • Adding a ProjectInstaller to the project. Here we go into drag-and-drop territory, with .Designer.cs files and toolboxes and magically generated InitializeComponent methods.
  • This ProjectInstaller should contain an instance of a ServiceProcessInstaller. This tells the installer under which account the service should run.
  • The ProjectInstaller also needs to contain one or more ServiceInstaller instances which tell the ...
  • ...

You get the gist, it is overly complex and involves too much automatically generated code and magic strings. Compare this to the beauty of a Topshelf service.

  • First you create a console app and add Topshelf through NuGet
  • Then, you create a class that holds your service logic. The only important thing is that the class must have some kind of Start and Stop method
  • and finally the main method of the Program.cs should look something like this
public static void Main()
{
    HostFactory.Run(c =>
    {
        c.Service<BookSyncService>(s =>
        {
           s.WhenStarted(tc => tc.Start());
           s.WhenStopped(tc => tc.Stop());
        });;

        c.UseNLog();

        c.SetServiceName("BookSync");
        c.SetDisplayName("Book Sync Service");
        c.SetDescription("Sync books");
    });
}

The result is a simple .exe file that you can use to install, uninstall, start and stop your Windows Service. To install it you simply go to the command-line and execute

.\yourservice.exe install

and the service will be configured in the Windows Service registry. Other operations are very similar and you can find more information in the full reference.

Conclusion

At first sight none of these libraries do something spectacular. They do however make your work lighter by simply taking care of some very mundane problems like background processing, reading CSV files or creating a Windows Service. And this is where there value comes from: they allow you to focus on the real challenges of your application. And as cheesy as it may be, that's a beautiful goal.