How to get started with TopShelf
Asked Answered
S

2

5

I recently discovered TopShelf. From everything I have read, it looks very cool. The only problem is that I have not been able to use it. I have to have missed something. Below is my code.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Topshelf;

namespace TestTopShelf {
public class FooBar {
    public FooBar() {

    }

    public void Start() { }
    public void Stop() { }
}

public class Program {
    public static void Main() {
        HostFactory.Run(x => {

            x.Service<FooBar>( s => { 

            });
        });
    }
}
}

You can see that it is a bit incomplete. When I am trying to set properties of the 's' object for ConstructUsing, WhenStarted, and WhenStopped Visual Studio is not inferring the correct type. I am new to lambda expressions and even newer to TopShelf, so I am not sure what I am doing.

I am using this page in the TopShelf documentation to get me started. It looks pretty straight forward, so I am not sure what I have missed.


updated code


using Autofac;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Topshelf;

namespace KeithLink.Svc.Windows.OrderService2 {
class FooBar {
    public FooBar() { }

    public void Start() { }
    public void Stop() { }
}

class Program {
    static void Main(string[] args) {
        HostFactory.Run(x => {

            x.Service<FooBar>(s => {
                s.ConstructUsing(name => new OrderService());
                s.WhenStarted(os => os.Start());
                s.WhenStopped(os => os.Stop());
            });

            x.RunAsLocalSystem();

            x.SetDescription("some service description");
            x.SetServiceName("ServiceName");
            x.SetDisplayName("Service Display Name");
        });
    }
}
}
Scuttle answered 15/9, 2014 at 16:42 Comment(6)
Is it not working the way your expect? If so, how do you think it should be working and how is it actually working? Are there errors? If so, what are they?Food
Although VisualStudio's intellisense doesn't infer the correct type, it should still compile. I don't know what topshelf is doing but I remember having those issues the last time I tried using it.Spire
@PeterRitchie when I declare s, it is giving me a message that says "Delegate 'System.Func<TestTopShelf.FooBar>' does not take 1 arguments" amongst 7 other errors.Scuttle
That's odd, because when I try the code you posted there are no compile errors. This is with TopShelf 3.1.122 from the current NuGet package.Food
So yes, that did work in my TestTopShelf project. I immediately tried moving this into a real development project. The class that I originally setup as the service started throwing that message. So I created the FooBar class again and it continued with the same error. I have updated the original post with the new code.Scuttle
It turns out that everything was messed up because the class I was calling did not have public methods for Start and Stop. I converted an existing service to a class and left the methods declared as protected. The correct answer was still from @tobsen. I will gladly accept the answer once he creates an answer.Scuttle
S
4

Although VisualStudio's intellisense doesn't infer the correct type, it should still compile. I don't know what topshelf is doing but I remember having those issues the last time I tried using it.

Spire answered 19/9, 2014 at 11:59 Comment(2)
How is this an answer?Amparoampelopsis
It is. Try it in VisualStudio2015 and see for yourself. Visual Studio complaints but it still compiles.Spire
F
4

When you want to "register" a service to run on startup with TopShelf you call the Service<T>.Run method--which you seem to have gotten started. In that method you are passed along a HostConfigurator object that you can tell (configure) TopShelf about your service. There's various things that you can configure about your service, but you generally want to tell it how to instantiate your service and how to stop and start it. you do that by passing in "code" that does these things. You can use a lambda to do that, for example:

public static void Main() {
    HostFactory.Run(x => {

        x.Service<FooBar>( s => { 
            s.ConstructUsing(name => new FooBar());
            s.WhenStarted(fb => fb.Start());
            s.WhenStopped(fb => fb.Stop());
        });
        x.RunAsLocalSystem(); // use the local system account to run as

        x.SetDescription("My Foobar Service");  // description seen in services control panel
        x.SetDisplayName("FooBar"); // friendly name seen in control panell
        x.SetServiceName("foobar"); // used with things like net stop and net start
    });
}

This code doesn't have to be lambdas, you could create methods to do this (as an example, this might be more clear):

    private static void Main(string[] args)
    {
        HostFactory.Run(x =>
        {
            x.Service<FooBar>(s =>
            {
                s.ConstructUsing(CreateService);
                s.WhenStarted(CallStart);
                s.WhenStopped(CallStop);
            });
            x.RunAsLocalSystem(); // use the local system account to run as

            x.SetDescription("My Foobar Service");  // description seen in services control panel
            x.SetDisplayName("FooBar"); // friendly name seen in control panell
            x.SetServiceName("foobar"); // used with things like net stop and net start
        });
    }

    private static void CallStop(FooBar fb)
    {
        fb.Stop();
    }

    private static void CallStart(FooBar fb)
    {
        fb.Start();
    }

    private static FooBar CreateService(HostSettings name)
    {
        return new FooBar();
    }

This gets your most or less started when a FooBar class, if there's something more specific, please update your question.

With these named methods, when TopShelf starts running (after the call to HostFactory.Run) your CreateSearch method would be called, then your CallStart method would be called, and when the service is stopped, your CallStop will be called.

Food answered 17/9, 2014 at 21:51 Comment(0)
S
4

Although VisualStudio's intellisense doesn't infer the correct type, it should still compile. I don't know what topshelf is doing but I remember having those issues the last time I tried using it.

Spire answered 19/9, 2014 at 11:59 Comment(2)
How is this an answer?Amparoampelopsis
It is. Try it in VisualStudio2015 and see for yourself. Visual Studio complaints but it still compiles.Spire

© 2022 - 2024 — McMap. All rights reserved.