NServiceBus Mailer

Component: NServiceBus Mailer
NuGet Package NServiceBus.Mailer (3.x)
This is a community run project
Target NServiceBus Version: 6.x

Introduction

Uses the NServiceBus Mailer project to send an email from both a saga and a handler.

Code Walk-through

Enable the Mailer feature

var mailer = endpointConfiguration.EnableMailer();

Configure the SmtpBuilder

This sample is hard coded to write all outgoing email to the filesystem at Path.Combine(Environment.CurrentDirectory, "Emails").

mailer.UseSmtpBuilder(
    buildSmtpClient: () =>
    {
        Directory.CreateDirectory(DirectoryLocation);
        return new SmtpClient
        {
            DeliveryMethod = SmtpDeliveryMethod.SpecifiedPickupDirectory,
            PickupDirectoryLocation = DirectoryLocation
        };
    });

Attachment logic

In this sample a fake attachment is added and no cleanup is necessary

mailer.UseAttachmentFinder(
    findAttachments: attachmentContext =>
    {
        var id = attachmentContext["Id"];
        var memoryStream = new MemoryStream(Encoding.ASCII.GetBytes("Hello"));
        var attachment = new Attachment(memoryStream, "example.txt", "text/plain");
        var attachments = new List<Attachment>
        {
            attachment
        };
        return Task.FromResult<IEnumerable<Attachment>>(attachments);
    },
    cleanAttachments: attachmentContext =>
    {
        // Attachment cleanup can be performed here
        return Task.CompletedTask;
    });

The Handler

public class MyHandler :
    IHandleMessages<MyMessage>
{
    static ILog log = LogManager.GetLogger<MyHandler>();

    public async Task Handle(MyMessage message, IMessageHandlerContext context)
    {
        var mail = new Mail
        {
            To = "to@fake.email",
            From = "from@fake.email",
            Body = "This is the body",
            Subject = "Hello from handler",
            AttachmentContext = new Dictionary<string, string>
            {
                {"Id", "fakeEmail"}
            }
        };
        await context.SendMail(mail)
            .ConfigureAwait(false);
        log.Info($"Mail sent and written to {Program.DirectoryLocation}");
    }
}

The Saga

public class MySaga :
    Saga<MySagaData>,
    IAmStartedByMessages<MyMessage>
{
    static ILog log = LogManager.GetLogger<MySaga>();

    public Task Handle(MyMessage message, IMessageHandlerContext context)
    {
        log.Info($"Mail sent and written to {Program.DirectoryLocation}");
        MarkAsComplete();
        var mail = new Mail
        {
            To = "to@fake.email",
            From = "from@fake.email",
            Body = "This is the body",
            Subject = "Hello from saga",
            AttachmentContext = new Dictionary<string, string>
            {
                {"Id", "fakeEmail"}
            }
        };
        return context.SendMail(mail);
    }

Running the Sample

When the solution is run 'enter' can be presses to send an initiating message. This message will be received by both the handler and the saga. Both handler and saga will send an email message which will be written to /bin/debug/emails/[GUID].eml.


Last modified