Microsoft were cool enough to record my talk at this year’s Goto Cph, even though the talk was on the Cloud and NoSQL track.
You can watch it here.
Afterwards, go check out all the other great presentations – it’s so cool they’ re made available!
Microsoft were cool enough to record my talk at this year’s Goto Cph, even though the talk was on the Cloud and NoSQL track.
You can watch it here.
Afterwards, go check out all the other great presentations – it’s so cool they’ re made available!
Update: If you want to read about Topshelf, please go to the updated guide to Topshelf, which covers how to get started with Topshelf 3
This is the first post in a series of posts on the open source service bus implementation, MassTransit. In order to push myself through learning it, I will do these posts as I go and document stuff I learn on the way.
This first post will be about one thing, that you’ll probably end up doing quite a few times while building your awesome messaging-based distributed system: Creating a service.
I’ve described how to use TopShelf before, but a lot has changed since then. TopShelf, at the time of writing, is now in version 2.2.1.0, and since 2.0 it has a feature called “shelving”, which is the ability to host any number of services beneath one Windows Service – just like IIS hosts web apps. This is pretty awesome, but today I’ll just show “the old API”, which IMO is still pretty slick!
First, make sure you have a working Ruby installation with Albacore ( gem install albacore). You’ll need these to build Topshelf.
Next, git clone git://github.com/phatboyg/Topshelf.git and build.bat. That should leave a bunch of binaries in the NET35 and NET40 folders beneath build_output. This is open source, baby!
Create a new “Console Application” and make sure to target the full .NET 4 framework (and not that bastard .NET 4 Client Profile thingie, which is default…)
Now add a reference to Topshelf.dll and log4net.dll. Punch in something like this:
1 2 3 4 5 6 7 8 9 10 11 12 |
class Program { static void Main() { HostFactory.Run(x => { x.SetDescription("MyBackend-description"); x.SetDisplayName("MyBackend-display-name"); x.SetServiceName("MyBackend-service-name"); }); } } |
This is all the necessary stuff to create a fully functional program, that can be run and debugged by running the resulting .exe – either from the command line, or with F5 inside Visual Studio.
Moreover, it can be installed as a Windows Service by going to the command line (as an administrator!) and executing NameOfYourApp.exe install. On my machine, I got this output:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
C:\temp\TransitDemo\Backend\bin\Debug>Backend.exe install Running a transacted installation. Beginning the Install phase of the installation. Installing service MyBackend-service-name.. Service MyBackend-service-name has been successfully installed. Creating EventLog source MyBackend-service-name in log Application... The Install phase completed successfully, and the Commit phase is beginning. The Commit phase completed successfully. The transacted install has completed. |
Now I can net start MyBackend-service-name and net stop MyBackend-service-name on the command line, or I can go to Windows’ service control snap-in and pull the usual levers to control it. Nifty!
Now I have a perfectly functioning Windows Service that does nothing at all! Let’s output some stuff to see where we’ll put our code in a short while. Try extending the x => { ... } lambda to make the program look like this:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
class Program { static void Main() { HostFactory.Run(x => { x.Service<MyBackend>(c => { c.SetServiceName("MyBackend"); c.ConstructUsing(() => new MyBackend()); c.WhenStarted(d => d.StartMyBackend()); c.WhenStopped(d => d.StopMyBackend()); }); x.SetDescription("MyBackend-description"); x.SetDisplayName("MyBackend-display-name"); x.SetServiceName("MyBackend-service-name"); }); } } |
and a class that looks something like this:
1 2 3 4 5 6 7 8 9 10 11 12 |
class MyBackend { public void StartMyBackend() { Console.WriteLine("Started!"); } public void StopMyBackend() { Console.WriteLine("Stopped!"); } } |
Now, when I press F5, wait a little, and press Ctrl + C, I get this output on the console:
1 2 3 |
Started! Stopped! Press any key to continue . . . |
Awesome, huh?
I really like how TopShelf now uses a Func<TService> to construct its service instance via ConstructUsing, instead of depending on the common service locator as the old TopShelf did. This way, I can pull the instance from an IoC container if I want.
In the next post I will take a look at how to send a message from a web application when someone tries to register as a user.