如何开始使用TopShelf

5

我最近发现了TopShelf。根据我所读到的所有信息,它看起来非常酷。唯一的问题是我无法使用它。我可能错过了什么。以下是我的代码。

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 => { 

            });
        });
    }
}
}

您可以看到这段代码有些不完整。当我尝试为ConstructUsing、WhenStarted和WhenStopped设置's'对象的属性时,Visual Studio并没有推断出正确的类型。我对lambda表达式和TopShelf都很陌生,所以我不确定自己在做什么。
我正在使用TopShelf文档中的此页面来入门。它看起来非常简单,所以我不知道自己错过了什么。
更新后的代码
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");
        });
    }
}
}

1
它是否没有按照你的期望工作?如果是这样,你认为它应该如何工作,实际上它又是如何工作的呢?是否有错误?如果有,那么是什么错误? - Peter Ritchie
1
尽管VisualStudio的智能感知无法推断正确的类型,但它仍应该编译。我不知道topshelf在做什么,但我记得上次尝试使用它时遇到了这些问题。 - tobsen
@PeterRitchie 当我声明s时,它会给我一个消息,上面写着“委托'System.Func<TestTopShelf.FooBar>'不接受1个参数”,还有其他7个错误。 - fizch
很奇怪,因为当我尝试你发布的代码时,没有编译错误。这是使用当前NuGet包中的TopShelf 3.1.122。 - Peter Ritchie
所以,是的,在我的TestTopShelf项目中确实起作用了。我立即尝试将其移植到实际开发项目中。我最初设置为服务的类开始抛出该消息。所以我再次创建了FooBar类,但它仍然显示相同的错误。我已经更新了原始帖子,添加了新代码。 - fizch
1
事实证明,一切都混乱了,因为我调用的类没有公共的Start和Stop方法。我将一个现有的服务转换为一个类,并将方法声明为受保护的。正确答案仍然来自@tobsen。他创建答案后,我将很乐意接受答案。 - fizch
2个回答

4
当你想要在启动时“注册”一个服务以在TopShelf上运行时,你需要调用Service<T>.Run方法,这个你好像已经开始了。在这个方法中,你会得到一个HostConfigurator对象,你可以告诉(配置)TopShelf关于你的服务的一些信息。有很多关于你的服务可以配置的东西,但是通常你想告诉它如何实例化你的服务以及如何停止和启动它。你可以通过传递执行这些操作的“代码”来实现这一点。例如,你可以使用lambda表达式:
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
    });
}

这段代码不一定要使用lambda表达式,你也可以创建方法来实现这个功能(比如下面的例子可能更容易理解):

    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();
    }

这将启动一个名为FooBar的类,如果有更具体的内容,请更新你的问题。
使用这些命名方法,当TopShelf开始运行(在调用HostFactory.Run后),将调用您的CreateSearch方法,然后将调用您的CallStart方法,并且在服务停止时,将调用您的CallStop

4

尽管VisualStudio的智能提示未推断出正确的类型,但仍应该可以编译。我不知道Topshelf在做什么,但我记得上次尝试使用它时也遇到了这些问题。


这怎么算是一个答案? - Fandango68
1
这是可以的。在VisualStudio2015中尝试一下,亲自体验一下。虽然Visual Studio会抱怨,但它仍然可以编译。 - tobsen

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接