DotLiquid.Mailer is a simple SMTP mailing service which uses DotLiquid as templating engine. DotLiquid is Ruby's Liquid Markup ported to the .net framework.
All base documentation is available from the DotLiquid Wiki pages. The test project implements some examples on how to use this Mailer plus a small filter collection and one custom tag and block taken from the official documentation pages.
This Library integrates viewmodel capability using the LiquidFunctions created by Olav Nybø. He also wrote a great article on this.
Current Version: 1.0.0.0
Get it from nuget.org/packages/DotLiquid.Mailer or via Package Manager Console
PM> Install-Package DotLiquid.Mailer
It is recommended to have smpt4dev running or a real mail server configured in order to see the delivery of the test emails.
Just instanciate a new MailEngine object (as IMailEngine) and do the apropriate settings.
public IMailEngine dotLiquidMailer;
dotLiquidMailer = new MailEngine()
{
DefaultFromAddress = "[email protected]",
IsHtml = true,
SmtpServer = "127.0.0.1",
SmtpPort = 25,
UseDefaultCredentials = true,
TemplateDir = @".\Templates"
};
DotLiquid.Mailer
may also be used as a Singleton, out of the box. All initialization and method
calls is done by setting the according properties or calling the methods of MailEngine.Instance
.
MailEngine.Instance.DefaultFromAddress = "[email protected]";
MailEngine.Instance.Send( ... );
Template file names passed to the SendFromFile
method are extended by the template directory,
if it is set with the TemplateDir
property. Here an example, passing data as a viewmodel class.
If the from
parameter is omitted with any Send*
metod then an initially set
DefaultFromAddress
will be taken.
// preparing the viewmodel
var orderData = new Order()
{
Cust = new Customer()
{
Salutation = "Dear Mr. Doe",
Firstname = "John",
Lastname = "Doe"
}
};
orderData.Itemlist.AddRange( new List<Item>()
{
new Item()
{
Name = "Apple",
Quantity = 5
},
new Item()
{
Name = "Banana",
Quantity = 10
}
});
// SendFromFile<T>(string subject, string templateFile, T data, string to, string from = "")
// sending the email with explicit from-address
mailer.SendFromFile<Order>("Your Order", "OrderConfirmation.liquid.html", orderData,
"[email protected]", "[email protected]")
// sending the email with default from-address
mailer.SendFromFile<Order>("Your Order", "OrderConfirmation.liquid.html", orderData,
"[email protected]")
This also works with anonymously created objects as data payload on any Send*
method.
// providing the template as string constant
public const string template =
"<!DOCTYPE html>" +
"<html lang='en' xmlns='http://www.w3.org/1999/xhtml'>" +
"<body>" +
"{{Cust.Salutation" +
" }" +
"},<br/><br/>" +
"thank you for the following order made for {{Cust.Firstname}} {{Cust.Lastname}}:" +
"" +
"<ul>" +
" {% for Item in Itemlist -%}" +
" <li>" +
" {{Item.Quantity}} x {{Item.Name}}" +
" </li>" +
" {% endfor -%}" +
"</ul>" +
"" +
"Your Sales Company." +
"</body>" +
"</html>";
// preparing data payload (as anonymous object)
data = new
{
Cust = new
{
Salutation = "Dear Mr. Doe",
Firstname = "John",
Lastname = "Doe"
},
ItemList = new[]
{
new {Name = "Apple", Quantity = 5},
new {Name = "Banana", Quantity = 10}
}
};
// Send<T>(string subject, string liquidTemplate, T data, string to, string from = "")
// injecting an anonymous object as data payload
mailer.Send("Your Order", template, _data, "[email protected]", "[email protected]");
// or if a default from-address is set:
mailer.Send("Your Order", template, _data, "[email protected]")
As the MailEngine
partly encapsulates the DotLiquid
engine it is possible to
register Tags and Blocks globally(!) using the RegisterTag
method. So they will
be available for any MailEngine instance.
// Tag
mailer.RegisterTag<RandomInt>("random");
var template ="Your lucky number is {% random 25 %}"
// Block
mailer.RegisterTag<ByChance>("bychance");
var template = "{% bychance 20 %}You're the lucky winner!{% endbychance %}";
Also custom filters can be registered globally(!) using the RegisterFilter
method.
mailer.RegisterFilter(typeof(CaseFilters));
Be aware of the naming of a filter when using it in a template. It depends on how you name your filter method. For example ...
var template = "{{'test object' | camelcase }}";
// if ...
public static string Camelcase(string input) { ... }
var template = "{{'test object' | camel_case }}"
// if ...
public static string CamelCase(string input) { ... }
Here is a description how to register a (pre initialized) MailerEngine with an Autofac container and how to resolve and use it.
// ---- registration ----
public IContainer container;
var builder = new ContainerBuilder();
builder.Register(c => new MailEngine()
{
DefaultFromAddress = "[email protected]",
IsHtml = true,
SmtpServer = "127.0.0.1",
SmtpPort = 25,
UseDefaultCredentials = true,
TemplateDir = @".\Templates"
})
.As<IMailEngine>();
container = builder.Build();
// ---- usage ----
var mailer = _container.Resolve<IMailEngine>();
// global Tag, Block and Filter registration
mailer.RegisterTag<RandomInt>("random");
mailer.RegisterTag<ByChance>("bychance");
mailer.RegisterFilter(typeof(CaseFilters));
// setting / sending
mailer.IsHigh = true;
mailer.SendFromFile("Your Order", "OrderConfirmation.liquid.html", data,
"[email protected]"));
The standard mailing priority is "normal". If an email shall be sent with high priority,
it is needed to set the property IsHigh
to true
, before sending the message. When
the apropriate email is sent it will be reset to "normal", again.
The MailEngine
provides two kinds of credentials to be set by their property: default
credentials and network credentials.
// configuring to use default credentials
mailer.UseDefaultCredentials = true;
// configuring to use network credentials
mailer.Credentials = new System.Net.NetworkCredential("myEmailServiceAccount", "Password");
The SSL encryption also can be turned "on" e. g. for seczrely sending a password with the credentiasls.
mailer.EnableSsl = true;
Version 1.0.0.0 - Initial release
Licensed under the MIT license.