Welcome to Chauffeur, deliverying changes to your Umbraco environment in style.
Creating a Deliverable is really quite simple, you need to do 3 things:
Deliverable
base classDeliverableName
attribute
Let’s start creating a basic Deliverable:
namespace MyUmbracoSite.Deliverables
{
[DeliverableName("awesome")]
public class AwesomeDeliverable : Deliverable
{
public AwesomeDeliverable(TextReader reader, TextWriter writer) : base(reader, writer)
{
}
}
}
So we’ve got our name, awesome
which is what we’ll use from Chauffeur to run our Deliverable, and we’ve got a public constructor that takes two arguments, a TextReader
and a TextWriter
. These are bound to public properties on the base class called In
and Out
and represent the two IO streams that you may want to interact with.
You might be wondering why you get these two dependencies injected rather than just using Console.ReaderLine
and Console.WriteLine
? Well the reason for that is to improve the ability to write unit tests. Chauffeur Deliverables are designed to be tested, and if you’re reading/writing to the console it’s pretty hard to write tests against them, instead we’ll use the raw streams which can be mocked or created yourself.
Now we have our Deliverable, and if you run Chauffeur.Runner.exe help
it’ll appear in the list. But it doesn’t do anything, so it’s time to make it do something. For that we’ll need to override the Run
method:
namespace MyUmbracoSite.Deliverables
{
[DeliverableName("awesome")]
public class AwesomeDeliverable : Deliverable
{
public AwesomeDeliverable(TextReader reader, TextWriter writer) : base(reader, writer)
{
}
public async override Task<DeliverableResult> Run(string command, string[] args)
{
await Out.WriteLineAsync("I'm an awesome deliverable!");
return DeliverableResult.Continue;
}
}
}
Congratulations, your Deliverable does something! It’s something simple, it writes a message to the output stream (ie: Console
) and then returns a success result.
The Run
method that we overrode has two arguments, command
and args
:
command
this is what the user typed at the command line to get into your deliverable (probably not all that useful, but you can use it to work out if they used an alias or not)args
an array of the space-separated arguments that were provided, use this to pull apart different operations for a Deliverable and arguments to themWe also need to return a state from the Deliverable, there are three results:
Shutdown
Continue
FinishedWithError
Most of the time you either want to return Continue
or Shutdown
, Continue
means you’re all good, keep going, Shutdown
will cause Chauffeur to exit is more useful if you’re doing something with a custom host.
Writing to the output stream is cool and all, but you probably want to do something more useful with it, like interact with Umbraco.
Let’s say you want to work with an Umbraco service as as the ContentTypeService
. Well, Chauffeur can give that to you! Chauffeur has a built-in IoC container that will inject any dependency (that’s registered) that you require to your constructor.
namespace MyUmbracoSite.Deliverables
{
[DeliverableName("awesome")]
public class AwesomeDeliverable : Deliverable
{
private readonly IContentTypeService contentTypeService;
public AwesomeDeliverable(TextReader reader, TextWriter writer, IContentTypeService contentTypeService) : base(reader, writer)
{
this.contentTypeService = contentTypeService;
}
public async override Task<DeliverableResult> Run(string command, string[] args)
{
var contentTypes = contentTypeService.GetAll();
foreach(var contentType in contentTypes)
await Out.WriteLineAsync($"Content Type named {contentType.Name} has an alias of {contentType.Alias}");
return DeliverableResult.Continue;
}
}
}
Now we’ve added a new constructor argument, which is an Umbraco service, and then we’ll get all the Content Types in our Run
method, then output their name and alias.
And there you go, you’ve created your first Deliverable! Next up learn how to unit test a Deliverable