Created
September 13, 2012 18:40
-
-
Save KevM/3716577 to your computer and use it in GitHub Desktop.
Example configuration of Topshelf to turn an console application into a Windows service
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class BootstrapService : ServiceControl | |
{ | |
private readonly HostSettings _settings; | |
private Container _container; | |
private CaseMonitor _monitor; | |
public BootstrapService(HostSettings settings) | |
{ | |
_settings = settings; | |
} | |
public bool Start(HostControl hostControl) | |
{ | |
hostControl.RequestAdditionalTime(TimeSpan.FromSeconds(10)); | |
_container = createContainer(); | |
_monitor = _container.With(_settings).GetInstance<CaseMonitor>(); | |
_monitor.Start(); | |
return true; | |
} | |
public bool Stop(HostControl hostControl) | |
{ | |
_monitor.Stop(); | |
return true; | |
} | |
public bool Pause(HostControl hostControl) | |
{ | |
return Stop(hostControl); | |
} | |
public bool Continue(HostControl hostControl) | |
{ | |
return Start(hostControl); | |
} | |
private static Container createContainer() | |
{ | |
var container = new Container(cfg => | |
{ | |
cfg.AddRegistry<SettingsProviderRegistry>(); | |
cfg.AddRegistry<BootstrapRegistry>(); | |
cfg.AddRegistry<ModelMapperRegistry>(); | |
cfg.Scan(s => | |
{ | |
s.TheCallingAssembly(); | |
s.WithDefaultConventions(); | |
s.AddAllTypesOf(typeof(ModelMap<>)); | |
}); | |
//this is only here because there is a current bug in StructureMap where add all types of a open generic don't work | |
cfg.For<ModelMap<RecentCaseModel>>().Use<RecentCaseMap>(); | |
}); | |
return container; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class CaseMonitor | |
{ | |
private readonly HostSettings _settings; | |
private readonly ILogger _logger; | |
private readonly ISystemTime _systemTime; | |
private readonly IModelBuilder<RecentCaseModel> _caseModelBuilder; | |
private DateTime _lastPolled; | |
private TimeSpan _interval; | |
private Timer _timer; | |
private IDisposable _loggingContext; | |
public CaseMonitor(HostSettings settings, ILogger logger, ISystemTime systemTime, IModelBuilder<RecentCaseModel> caseModelBuilder) | |
{ | |
_settings = settings; | |
_logger = logger; | |
_systemTime = systemTime; | |
_caseModelBuilder = caseModelBuilder; | |
_interval = TimeSpan.FromSeconds(15); | |
_lastPolled = systemTime.Now.Subtract(_interval); | |
} | |
public bool Start() | |
{ | |
//The logging context will have the instance of this windows service just in case there are multiple services. | |
//This is done just to show a scenario for consuming the host settings object we get from Topshelf. | |
_loggingContext = _logger.Push(_settings.InstanceName); | |
//create a timer in charge of doing the recurreing polling for open cases | |
_timer = new Timer(_interval.TotalMilliseconds); | |
_timer.Elapsed += pollForOpenCases; | |
_timer.Start(); | |
return true; | |
} | |
private void pollForOpenCases(object sender, ElapsedEventArgs elapsedEventArgs) | |
{ | |
var from = _lastPolled; | |
var to = _systemTime.Now; | |
//using a ModelMap to project cases created between the last poll and now | |
var cases = _caseModelBuilder.Get(f => f.Between("creation_time", from, to)); | |
_logger.LogInfo("{0} cases were created in the last {1} seconds", cases.Length, to.Subtract(from).TotalSeconds); | |
foreach (var kase in cases) | |
{ | |
//the debug log will have more details | |
_logger.LogDebug(kase.ToString()); | |
} | |
_lastPolled = to; | |
} | |
public bool Stop() | |
{ | |
_timer.Stop(); | |
_loggingContext.Dispose(); | |
return true; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class RecentCaseMap : ModelMap<RecentCaseModel> | |
{ | |
protected override void MapDefinition() | |
{ | |
FromView("qry_case_view") | |
.Assign(d => d.Id).FromIdentifyingField("id_number") | |
.Assign(d => d.Title).FromIdentifyingField("title"); | |
} | |
} | |
//The object which we'll be populating using ModelMap. | |
public class RecentCaseModel | |
{ | |
public string Title { get; set; } | |
public string Id { get; set; } | |
public override string ToString() | |
{ | |
return String.Format("Case {0} with title {1}", Id, Title); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class Program | |
{ | |
static int Main(string[] args) | |
{ | |
return (int) HostFactory.Run(c => | |
{ | |
c.SetServiceName("dtbootstrap-casemonitor"); | |
c.SetDisplayName("Dovetail Bootstrap Case Monitor"); | |
c.SetDescription("This is an example of how to implement a windows service that uses the Dovetail Bootstrap library facilitating development of Dovetail SDK applications"); | |
c.RunAsNetworkService(); | |
c.EnablePauseAndContinue(); | |
c.Service(settings => new BootstrapService(settings)); | |
c.UseLog4Net("bootstrap.log4net"); | |
//There is a lot more you can do here to configure your service using Topshelf | |
// http://docs.topshelf-project.com/en/latest/configuration/index.html | |
}); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment