使用Topshelf轻松创建Windows服务

目录

介绍

入门

示例1-基本的winservice

所需的NuGet软件包

Topshelf

Bootstrap.cs

示例2-Scheduledservice

所需的NuGet软件包

Topshelf

Bootstrap.cs

Quartz

注册日志提供者

示例3-ScheduledEFCoreWinservice

所需的NuGet软件包

Topshelf

Bootstrap.cs

带有依赖注入的EF Core

Quartz

注册日志提供者

示例4-WebapiWinservice

所需的NuGet软件包

Topshelf

项目设置

appsettings.json

发布提示

调试

Bootstrap.cs

WebApi

带有依赖注入的EF Core


本文向您展示如何使用SchedulerEntity Framework Core或使用Kestrel服务器托管WebApi来运行简单的Windows服务。

介绍

这些示例的核心库是Topshelf。它提供了一种非常简单的方法来开始使用winservices。本文包含winservices的示例,这些示例应执行计划的作业或运行RestApi

所有示例都在使用Dependency Injection,如果您不熟悉它,这里有一些有关Dependency InjectionAutofac框架的进一步阅读。

入门

  • 所有示例均基于.NET Core 3.1

示例1-基本的winservice

所需的NuGet软件包

Topshelf

  • 执行EXE将在控制台中运行该服务
  • 可以通过cmd.exe(以管理员身份运行)安装Windowsservice——Service.exe install
  • 要卸载,请使用 Service.exe uninstall

Bootstrap.cs

此类用于注册依赖项注入的类型。在此示例中,必须注册包含服务逻辑的BasicService

示例2-Scheduledservice

所需的NuGet软件包

  • Topshelf
  • Topshelf.Autofac
  • Quartz
  • Autofac.Extras.Quartz
  • Microsoft.Extensions.Configuration.Json

Topshelf

  • 执行EXE将在控制台中运行该服务
  • 可以通过cmd.exe(以管理员身份运行)安装Windowsservice——Service.exe install
  • 要卸载,请使用 Service.exe uninstall

Bootstrap.cs

此类用于注册依赖项注入的类型。

  • 注册 Servicecontrollers
  • 注册IConfiguration——提供阅读appsettings.json的信息
  • 设置注册——Helperclass,可更轻松地访问配置
  • 注册 QuartzModule
  • 控制器注册

Quartz

日志

如果未执行作业,请打开Quartz的日志记录。该QuartzConsoleLogProvider.cs实现其登录到控制台的记录器。

注册日志提供者

LogProvider.SetCurrentLogProvider(new QuartzConsoleLogProvider());

作业

作业(Job)是您的服务应运行的任务。这些必须实现IJob接口。如果此作业需要一些其他数据,则可以使用JobDataMap。(参见《QuartzController.cs》和MyJob.cs

触发器

Quarzt提供了一些触发器来在特定时间执行作业。QuartzController.cs中提供了示例

  • 一次执行作业。
  • 间隔执行作业。
  • 从队列中删除作业。

触发器说明文件

示例3-ScheduledEFCoreWinservice

所需的NuGet软件包

  • Topshelf
  • Topshelf.Autofac
  • Quartz
  • Autofac.Extras.Quartz
  • Microsoft.Extensions.Configuration.Json
  • Microsoft.EntityFrameworkCore
  • Microsoft.EntityFrameworkCore.SqlServer
  • Microsoft.EntityFrameworkCore.Tools

Topshelf

  • 执行EXE将在控制台中运行该服务
  • 可以通过cmd.exe(以管理员身份运行)安装Windowsservice——Service.exe install
  • 要卸载,请使用 Service.exe uninstall

Bootstrap.cs

此类用于注册依赖项注入的类型。

  • 注册 Servicecontrollers
  • 注册IConfiguration——提供阅读appsettings.json的信息
  • 设置注册——Helperclass便于访问配置
  • 注册 QuartzModule
  • 注册 Controller
  • 注册数据库上下文

带有依赖注入的EF Core

数据库

示例数据库是免费Ip2Location数据库的导入。有关下载和导入到MS-SQL的说明,请检查以下链接:IP2Location™LITE IP-COUNTRY数据库

Bootstrap

InstancePerLifetimeScope——将为每个作业创建上下文,并在完成作业后将其丢弃。

builder.RegisterType<ip2locationContext>().InstancePerLifetimeScope();
builder.RegisterType<ip2locationWriteContext>().InstancePerLifetimeScope();

Context

配置将因为构造函数ip2locationContext(IConfiguration configuration)而自动注入。该配置用于读取连接字符串。

public partial class ip2locationContext : DbContext
{
    protected readonly IConfiguration _configuration;

    public ip2locationContext(IConfiguration configuration)
    {
        _configuration = configuration;
    }

    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        if (!optionsBuilder.IsConfigured)
        {
            optionsBuilder.UseSqlServer(_configuration.GetConnectionString("CTX"));
        }
    }
}

ip2locationContextFactory

如果要进行EF-Core迁移,则应实现此类。否则,EF-Core工具将找不到您的连接字符串。

Quartz

日志

如果未执行作业,请打开Quartz的日志记录。该QuartzConsoleLogProvider.cs实现其登录到控制台的记录器。

注册日志提供者

LogProvider.SetCurrentLogProvider(new QuartzConsoleLogProvider());

作业

作业(Job)是您的服务应运行的任务。这些必须实现IJob接口。如果此作业需要一些其他数据,则可以使用JobDataMap。(请参见《QuartzController.cs》和MyJob.cs

触发器

Quarzt提供了一些触发器来在特定时间执行作业。QuartzController.cs中提供了示例

  • 一次执行作业。
  • 间隔执行作业。
  • 从队列中删除作业。

触发器说明文件

示例4-WebapiWinservice

所需的NuGet软件包

  • Topshelf
  • Topshelf.Autofac
  • Microsoft.Extensions.Configuration.Json
  • Microsoft.EntityFrameworkCore
  • Microsoft.EntityFrameworkCore.SqlServer
  • Microsoft.EntityFrameworkCore.Tools
  • Microsoft.AspNetCore
  • Microsoft.AspNetCore.Core
  • Microsoft.AspNetCore.Server.Kestrel.Core
  • Microsoft.Extensions.Hosting
  • Microsoft.Extensions.Logging.Configuration

Topshelf

  • 执行EXE将在控制台中运行该服务
  • 可以通过cmd.exe(以管理员身份运行)安装Windowsservice——Service.exe install
  • 要卸载,请使用 Service.exe uninstall

项目设置

  1. 控制台应用程序(.NET Core 3.1
    • 用于Windows服务
    • 打开Projectfile——将项目SDK编辑为: <Project Sdk="Microsoft.NET.Sdk.Web">
  2. 类别库(.NET STandard 2.0
    • 如果C#应用程序需要responseobject,则创建一个类库。或者,您可以只使用从JSON解析的动态对象。

appsettings.json

  • 必须配置部分KestrelLogging
  • “AllowedHosts”“192.168.130.16; test.example.com”——使用该配置,您可以定义可以从哪些主机访问WebApi

发布提示

  • 应该配置AllowedHosts 
  • 如果API仅在内部可用,请配置Windows防火墙

调试

!!! 不要用IIS-Express执行!

Bootstrap.cs

此类用于注册依赖项注入的类型。

BuildContainer

  • 注册 servicecontroller

RegisterGlobalTypes

这些类型必须注册两次。一次用于ASP.NET虚拟主机,一次用于服务控制器。

  • 注册IConfiguration——提供阅读appsettings.json的信息
  • 设置注册—— Helperclass便于访问配置

WebApi

初始化

建立虚拟主机

定义Kestrel服务器的设置:

_webHost = Host.CreateDefaultBuilder()
    .ConfigureWebHostDefaults(webBuilder =>
    {
        webBuilder.UseStartup<Startup>();
        webBuilder.ConfigureKestrel(serverOptions =>
        {
            serverOptions.Limits.MaxConcurrentConnections = 100;
            serverOptions.Limits.MaxConcurrentUpgradedConnections = 100;
            serverOptions.Limits.MaxRequestBodySize = 30 * 1024 * 1024;
            serverOptions.Limits.MinRequestBodyDataRate =
                new MinDataRate(bytesPerSecond: 100,
                    gracePeriod: TimeSpan.FromSeconds(10));
            serverOptions.Limits.MinResponseDataRate =
                new MinDataRate(bytesPerSecond: 100,
                    gracePeriod: TimeSpan.FromSeconds(10));
            serverOptions.Limits.KeepAliveTimeout =
                TimeSpan.FromMinutes(2);
            serverOptions.Limits.RequestHeadersTimeout =
                TimeSpan.FromMinutes(1);
        });
    })
    .UseServiceProviderFactory(new AutofacServiceProviderFactory())
    .Build();

Startup.cs

配置容器

注册Autofac的类型

public void ConfigureContainer(ContainerBuilder builder)
{
    Bootstrap.RegisterGlobalTypes(builder);
    builder.RegisterType<Ip2LocationController>();
    // is used for determining the client ip
    builder.RegisterType<HttpContextAccessor>().As<IHttpContextAccessor>().SingleInstance();
    // context per request
    builder.RegisterType<ip2locationContext>().InstancePerLifetimeScope();
}

配置

如果HostHttpsRedirect设置为« 1»,该服务将自动重定向到HTTPS

Settings settings = app.ApplicationServices.GetAutofacRoot().Resolve<Settings>();
if (settings.GetAppSetting("HostHttpsRedirect") == "1")
{
    app.UseHttpsRedirection();
}

开始/停止

// Start
_webHost.StartAsync().ConfigureAwait(false).GetAwaiter().GetResult();
// Stop 
_webHost.StopAsync().ConfigureAwait(false).GetAwaiter().GetResult();

ApiController

  1. 继承自 ControllerBase
  2. 设置属性RouteApiController
  3. 实现HttpGet/HttpPost方法

C#客户端示例

项目« WebapiWinserviceClientExample»

带有依赖注入的EF Core

数据库

示例数据库是免费Ip2Location数据库的导入。有关下载和导入到MS-SQL的说明,请检查以下链接:IP2Location™LITE IP-COUNTRY数据库

Bootstrap

InstancePerLifetimeScope——将为每个作业创建上下文,并在完成作业后将其丢弃。

builder.RegisterType<ip2locationContext>().InstancePerLifetimeScope();
builder.RegisterType<ip2locationWriteContext>().InstancePerLifetimeScope();

Context

配置将因为构造函数ip2locationContext(IConfiguration configuration)而自动注入。该配置用于读取连接字符串。

public partial class ip2locationContext : DbContext
{
    protected readonly IConfiguration _configuration;

    public ip2locationContext(IConfiguration configuration)
    {
        _configuration = configuration;
    }

    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        if (!optionsBuilder.IsConfigured)
        {
            optionsBuilder.UseSqlServer(_configuration.GetConnectionString("CTX"));
        }
    }
}

ip2locationContextFactory

如果要进行EF-Core迁移,则应实现此类。否则,EF-Core工具将找不到您的连接字符串。

发布了69 篇原创文章 · 获赞 146 · 访问量 49万+

猜你喜欢

转载自blog.csdn.net/mzl87/article/details/104806160