Chegamos ao último capítulo da série. Até agora já implementamos o monitor de diretórios, o executor de tarefas e ligamos eles à camada de negócios através da controller. No caminho, fizemos uma breve pausa para mostrar como testar a controller. Agora é a hora de finalmente criar o Windows services e juntar todas as peças da solução.
Quem utiliza o VSTS tem a vantagem de ter um template para criar Windows services. Quem utiliza as outras versões do VS, precisa implementar serviço na unha, do zero, como farei aqui.
Começamos criando um novo projeto, do tipo class library, chamado WinServiceSample. Na configuração do projeto, em Project > Properties ..., vamos alterar o output type de “Class library” para “Console Application”. Adicionamos referência à dll System.ServiceProcess. Neste projeto criamos a classe WinService, que herda de System.ServiceProcess.ServiceBase. Esta classe abstrata já nos fornece tudo o que precisamos para que a classe se torne um serviço.
Para colocar o serviço para funcionar temos que sobrescrever dois métodos da classe mãe: OnStart e OnStop. Com eles definimos o que acontece quando o serviço inicia e pára. Outros métodos também podem ser sobrescritos, como OnPause ou OnContinue, mas isto é opcional. Fundamental são os dois primeiros, sem eles, o serviço roda, mas não faz nada.
Utilizamos o método construtor para configurar o serviço e fornecer algumas informações importantes para a infra-estrutura, como o nome do serviço e a definição de quais operações são permitidas.
Por último é necessário criar um método estático main, que será o responsável por criar uma instância de si próprio e incluí-la na lista de serviço, através do método Run da classe ServiceBase.
Este foi todo o código necessário para o serviço. Agora sim vamos implementar a nossa parte, que é colocar o serviço para trabalhar para gente.
Como precisamos do Windsor para criar a instância da controller, precisamos adicionar a referência ao Castle.MicroKernel e Castle.Windsor. Precisamos ainda de duas variáveis, um container, do tipo WindsorContainer e um controller, do tipo IWinSvcController. Depois, no construtor, utilizo o container para instanciar um controller. Por último, simplesmente chamo os métodos Start e Stop da controller nos devidos momentos.
public class WinService : ServiceBase
{
public static void Main()
{
Run(new WinService());
}
private readonly IWinSrvController controller;
private readonly WindsorContainer container = new WindsorContainer(new XmlInterpreter());
public WinService()
{
ServiceName = "Meu servico";
CanStop = true;
CanPauseAndContinue = false;
AutoLog = true;
controller = container.Resolve<IWinSrvController>();
}
protected override void OnStart(string[] args)
{
controller.Start();
}
protected override void OnStop()
{
controller.Stop();
}
}
Pronto, meu serviço está pronto. Falta pouco para acabar, preciso apenas incluir os instaladores do serviço. No “Solution Explorer” clique com o botão direito sobre a classe WinService e selecione “View designer” . Na janela “Properties” aparecerá um link Add service, não é muito visível, por isto a figura abaixo. Antes de clicar preencha o nome do serviço na propriedade ServiceName, caso contrário ocorrerá um erro no processo.
O VS irá incluir uma classe, com dois componentes, no projeto. No componente ServiceInstaller você deve configurar:
- Se o seu serviço iniciará manual ou automaticamente.
- O DisplayName, com o nome que seu serviço terá no Service manager
Clicando no outro componente, ServiceProcessInstaller, você deve configurar:
- Que usuário irá rodar o serviço e, conseqüentemente, o seu contexto de segurança.
Compilando a solução tenho em mãos o executável WinService.exe. Mas para este aplicativo ser executado como um Windows service eu preciso instalá-lo e não executá-lo. Para fazer isto utilizo um utilitário do .Net Framework SDK, chamado installutil. Como mostra a figura abaixo, basta chamar o installutil, mandando o caminho para o executável. Para desinstalá-lo, basta adiocionar o parâmetro “/u”.
Na linha seguinte inicio meu serviço com o comando “net start”. Também posso fazer isto através do Service manager, em Start > Administrative Tools > Services.
Conclusão
Chegamos ao final da jornada, um pouco mais longa do que alguns esperavam, mas espero que recompensadora. Como resultado, temos uma solução que tem boa capacidade de manutenção e extensão. É inegável que a solução é mais complexa do que simplesmente criar um Windows service e jogar tudo o que você precisa lá dentro. A pergunta é: Você precisa de tudo isto para a sua solução? E resposta só você sabe, pois ela varia caso a caso.