TopShelf 2.0
Working on making Topshelf 2.0 ready for release. I think we’re mostly feature complete for our 2.0 release, just working on fixing any left over bugs.
So what is changing in Topshelf 2.0?
InIsolationis no longer an option when creating new services. Support for hosting multiple AppDomains has been moved into shelving. More on shelving to follow.- Command line arguments have changed a bit. See the website’s documentation on command line syntax for updates there.
- The communication between all subsystems, such as “start up services”, is now all down via messages sent across channels. This allows us to easily move to sending messages across AppDomains.
- Shelving! More on this below.
Shelving
So what is this new shelving? It is building Topshelf to be a service host, where when you drop files in a directory, it can look for an interface implementation and spin up a new AppDomain with that logical service isolated in that AppDomain. If you update the files in that folder, the service will attempt to cleanly shutdown then restart with the new files. It’s pretty awesome, if I do say so myself.
Why is it awesome?
- Deploying services is dead simple
xcopynow, instead of stop service, uninstall, copy, install, start - Configuration changes automagically restart the service when saved – similar to IIS
- Need to scale out a new service? Just drop a new directory in the Service folder and you can scale easily!
Here’s a simple example.
Now compare that to the sample service in the old style.
Shelved services are just DLL assemblies, Topshelf has a Host program that is the windows service that logical services will run under. The second example is a full program that would be installed as a service.
I’m getting exceptions when parsing command line arguments using the latest source. More here: http://github.com/Topshelf/Topshelf/issues#issue/4
Cheers,
Steve
Does TopShelf still support starting winforms GUIs? If so, I am seeing an odd exception and was wondering if you could point me at an example.
Here’s the exception: FATAL – Aug 13 3:13:16 PM – Thread ..1 executing ..53\src\Topshelf\Runner.cs:(37) reports “Host encountered an unhandled exception on the AppDomain”
System.InvalidCastException: Unable to cast object of type ‘Magnum.CommandLineParser.DefinitionElement’ to type ‘Magnum.CommandLineParser.IArgumentElement’.
at Topshelf.TopshelfArgumentParser.b__0(ICommandLineElement x) in d:\BuildAgent-01\work\36648179956fb453\src\Topshelf\TopshelfArgumentParser.cs:line 34
at System.Linq.Enumerable.c__DisplayClass12`3.b__11(TSource x)
at System.Linq.Enumerable.WhereSelectEnumerableIterator`2.MoveNext()
at System.Linq.Enumerable.d__a5`1.MoveNext()
at System.Linq.Enumerable.SingleOrDefault[TSource](IEnumerable`1 source)
at Topshelf.TopshelfArgumentParser.Set(TopshelfArguments args, IEnumerable`1 commandLineElements) in d:\BuildAgent-01\work\36648179956fb453\src\Topshelf\Tops
helfArgumentParser.cs:line 32
at Topshelf.TopshelfArgumentParser.Parse(String commandLine) in d:\BuildAgent-01\work\36648179956fb453\src\Topshelf\TopshelfArgumentParser.cs:line 25
at Topshelf.Runner.Host(RunConfiguration configuration, String[] args) in d:\BuildAgent-01\work\36648179956fb453\src\Topshelf\Runner.cs:line 49
at Kilauea.Scheduler.ConfigurationPlan`1.Host(String[] args) in F:\SVN\products\kilauea\branches\api-scheduler\src\Kilauea.Scheduler\ConfigurationPlan.cs:lin
e 130
at Kilauea.Scheduler.Runtime.Program.Main(String[] args) in F:\SVN\products\kilauea\branches\api-scheduler\src\Kilauea.Scheduler.Runtime\Program.cs:line 11
FATAL – Aug 13 3:13:16 PM – Thread ..1 executing ..53\src\Topshelf\Runner.cs:(37) reports “Host encountered an unhandled exception on the AppDomain”
System.InvalidCastException: Unable to cast object of type ‘Magnum.CommandLineParser.DefinitionElement’ to type ‘Magnum.CommandLineParser.IArgumentElement’.
at Topshelf.TopshelfArgumentParser.b__0(ICommandLineElement x) in d:\BuildAgent-01\work\36648179956fb453\src\Topshelf\TopshelfArgumentParser.cs:line 34
at System.Linq.Enumerable.c__DisplayClass12`3.b__11(TSource x)
at System.Linq.Enumerable.WhereSelectEnumerableIterator`2.MoveNext()
at System.Linq.Enumerable.d__a5`1.MoveNext()
at System.Linq.Enumerable.SingleOrDefault[TSource](IEnumerable`1 source)
at Topshelf.TopshelfArgumentParser.Set(TopshelfArguments args, IEnumerable`1 commandLineElements) in d:\BuildAgent-01\work\36648179956fb453\src\Topshelf\Tops
helfArgumentParser.cs:line 32
at Topshelf.TopshelfArgumentParser.Parse(String commandLine) in d:\BuildAgent-01\work\36648179956fb453\src\Topshelf\TopshelfArgumentParser.cs:line 25
at Topshelf.Runner.Host(RunConfiguration configuration, String[] args) in d:\BuildAgent-01\work\36648179956fb453\src\Topshelf\Runner.cs:line 49
The argument being passed in is “gui” or “/gui” and is not null when it’s handed over to Runner.cs.