目录
介绍
入门
示例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
本文向您展示如何使用Scheduler,Entity Framework Core或使用Kestrel服务器托管WebApi来运行简单的Windows服务。
介绍这些示例的核心库是Topshelf。它提供了一种非常简单的方法来开始使用winservices。本文包含winservices的示例,这些示例应执行计划的作业或运行RestApi。
所有示例都在使用Dependency Injection,如果您不熟悉它,这里有一些有关Dependency Injection和Autofac框架的进一步阅读。
- 维基百科
- 依赖注入解释
- DI的好处-Stackexchange
- Autofac
- Autofac文档
- 所有示例均基于.NET Core 3.1
- 参见Github:BasicWinservice
- Topshelf
- Topshelf.Autofac
- 执行EXE将在控制台中运行该服务
- 可以通过cmd.exe(以管理员身份运行)安装Windowsservice——Service.exe install
- 要卸载,请使用 Service.exe uninstall
此类用于注册依赖项注入的类型。在此示例中,必须注册包含服务逻辑的BasicService。
示例2-Scheduledservice- 参见Github:ScheduledWinservice
- Topshelf
- Topshelf.Autofac
- Quartz
- Autofac.Extras.Quartz
- Microsoft.Extensions.Configuration.Json
- 执行EXE将在控制台中运行该服务
- 可以通过cmd.exe(以管理员身份运行)安装Windowsservice——Service.exe install
- 要卸载,请使用 Service.exe uninstall
此类用于注册依赖项注入的类型。
- 注册 Servicecontrollers
- 注册IConfiguration——提供阅读appsettings.json的信息
- 设置注册——Helperclass,可更轻松地访问配置
- 注册 QuartzModule
- 控制器注册
日志
如果未执行作业,请打开Quartz的日志记录。该QuartzConsoleLogProvider.cs实现其登录到控制台的记录器。
注册日志提供者LogProvider.SetCurrentLogProvider(new QuartzConsoleLogProvider());
作业
作业(Job)是您的服务应运行的任务。这些必须实现IJob接口。如果此作业需要一些其他数据,则可以使用JobDataMap。(参见《QuartzController.cs》和MyJob.cs)
触发器
Quarzt提供了一些触发器来在特定时间执行作业。QuartzController.cs中提供了示例:
- 一次执行作业。
- 间隔执行作业。
- 从队列中删除作业。
触发器说明文件
示例3-ScheduledEFCoreWinservice- 参见Github:ScheduledEFCoreWinservice
- Topshelf
- Topshelf.Autofac
- Quartz
- Autofac.Extras.Quartz
- Microsoft.Extensions.Configuration.Json
- Microsoft.EntityFrameworkCore
- Microsoft.EntityFrameworkCore.SqlServer
- Microsoft.EntityFrameworkCore.Tools
- 执行EXE将在控制台中运行该服务
- 可以通过cmd.exe(以管理员身份运行)安装Windowsservice——Service.exe install
- 要卸载,请使用 Service.exe uninstall
此类用于注册依赖项注入的类型。
- 注册 Servicecontrollers
- 注册IConfiguration——提供阅读appsettings.json的信息
- 设置注册——Helperclass便于访问配置
- 注册 QuartzModule
- 注册 Controller
- 注册数据库上下文
数据库
示例数据库是免费Ip2Location数据库的导入。有关下载和导入到MS-SQL的说明,请检查以下链接:IP2Location™LITE IP-COUNTRY数据库。
Bootstrap
InstancePerLifetimeScope——将为每个作业创建上下文,并在完成作业后将其丢弃。
builder.RegisterType().InstancePerLifetimeScope();
builder.RegisterType().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- 参见Github:WebapiWinservice
- 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
- 执行EXE将在控制台中运行该服务
- 可以通过cmd.exe(以管理员身份运行)安装Windowsservice——Service.exe install
- 要卸载,请使用 Service.exe uninstall
- 控制台应用程序(.NET Core 3.1)
- 用于Windows服务
- 打开Projectfile——将项目SDK编辑为:
- 类别库(.NET STandard 2.0)
- 如果C#应用程序需要responseobject,则创建一个类库。或者,您可以只使用从JSON解析的动态对象。
- 必须配置部分Kestrel和Logging。
- “AllowedHosts”:“192.168.130.16; test.example.com”——使用该配置,您可以定义可以从哪些主机访问WebApi。
- 应该配置AllowedHosts
- 如果API仅在内部可用,请配置Windows防火墙
!!! 不要用IIS-Express执行!
此类用于注册依赖项注入的类型。
BuildContainer
- 注册 servicecontroller
RegisterGlobalTypes
这些类型必须注册两次。一次用于ASP.NET虚拟主机,一次用于服务控制器。
- 注册IConfiguration——提供阅读appsettings.json的信息
- 设置注册—— Helperclass便于访问配置
初始化
建立虚拟主机
定义Kestrel服务器的设置:
_webHost = Host.CreateDefaultBuilder()
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup();
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();
// is used for determining the client ip
builder.RegisterType().As().SingleInstance();
// context per request
builder.RegisterType().InstancePerLifetimeScope();
}
配置
如果HostHttpsRedirect设置为« 1»,该服务将自动重定向到HTTPS。
Settings settings = app.ApplicationServices.GetAutofacRoot().Resolve();
if (settings.GetAppSetting("HostHttpsRedirect") == "1")
{
app.UseHttpsRedirection();
}
开始/停止
// Start
_webHost.StartAsync().ConfigureAwait(false).GetAwaiter().GetResult();
// Stop
_webHost.StopAsync().ConfigureAwait(false).GetAwaiter().GetResult();
ApiController
- 继承自 ControllerBase
- 设置属性Route和ApiController
- 实现HttpGet/HttpPost方法
C#客户端示例
项目« WebapiWinserviceClientExample»。
带有依赖注入的EF Core数据库
示例数据库是免费Ip2Location数据库的导入。有关下载和导入到MS-SQL的说明,请检查以下链接:IP2Location™LITE IP-COUNTRY数据库。
Bootstrap
InstancePerLifetimeScope——将为每个作业创建上下文,并在完成作业后将其丢弃。
builder.RegisterType().InstancePerLifetimeScope();
builder.RegisterType().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工具将找不到您的连接字符串。