Aspnet Zero中使用Windows service (Topshelf)来承载Quartz.net任务
Aspnet Zero使用Windows service (Topshelf)来承载Quartz.net任务
网上有很多关于如何使用Topshelf创建ABP的Quartz windows服务,但很少(没有)有介绍如何配合Aspnet Zero使用的文章,本文记录集成过程,以供参考。
在官方Aspnet Zero模板解决方案中建立Console类型的项目,并安装以下buget package:
Topshelf
Abp.Quartz
Abp.Castle.Log4Net
Abp.AspnetCore
(后面有用到)添加引用
MyCompanyName.AbpZeroTemplate.Core
和MyCompanyName.AbpZeroTemplate.Core
项目最终引用如图:
创建Module文件,
- 添加相关DependsOn属性;
abpZeroTemplateEntityFrameworkCoreModule.SkipDbSeed = true;
这里我们需要禁用数据库初始化动作,因为所有的初始化动作都在Host端完成;- 设置数据库连接字符串
Configuration.DefaultNameOrConnectionString = _appConfiguration.GetConnectionString( AbpZeroTemplateConsts.ConnectionStringName );
最终文件如下:
namespace MyCompanyName.AbpZeroTemplate.WinService
{
[DependsOn(typeof(AbpZeroTemplateCoreModule),
typeof(AbpZeroTemplateEntityFrameworkCoreModule),
typeof(AbpQuartzModule)
)]
public class AbpZeroWinServiceModule : AbpModule
{
private readonly IConfigurationRoot _appConfiguration; public AbpZeroWinServiceModule(AbpZeroTemplateEntityFrameworkCoreModule abpZeroTemplateEntityFrameworkCoreModule)
{
abpZeroTemplateEntityFrameworkCoreModule.SkipDbSeed = true; _appConfiguration = AppConfigurations.Get(
typeof(AbpZeroWinServiceModule).GetAssembly().GetDirectoryPathOrNull(),
addUserSecrets: true
);
} public override void PreInitialize()
{
//Set default connection string
Configuration.DefaultNameOrConnectionString = _appConfiguration.GetConnectionString(
AbpZeroTemplateConsts.ConnectionStringName
);
} public override void Initialize()
{
this.IocManager.RegisterAssemblyByConvention(Assembly.GetExecutingAssembly()); }
}
}
修改Program.cs文件
- 设置工作目录
Directory.SetCurrentDirectory(currentDirectory);
, 目的是为了保证工作在windows service时log文件存放目录正确,如果不设置, 工作在windows service时log文件将会存放在system32目录中 - 注册IdentityRegistrar以及添加abp依赖,这一步是必须的,否则会出现依赖错误:
Castle.MicroKernel.Handlers.HandlerException: 'Can't create component 'Portal.Authorization.Users.UserManager' as it has dependencies to be satisfied.
添加abp依赖的同时我们同时添加log4net和插件支持.(注意路径)var services = new ServiceCollection();
IdentityRegistrar.Register(services); services.AddAbp<AbpZeroWinServiceModule>(options =>
{
//Configure Log4Net logging
options.IocManager.IocContainer.AddFacility<LoggingFacility>(
f => f.UseAbpLog4Net().WithConfig(Path.Combine(currentDirectory, $"log4net.config"))
); options.PlugInSources.AddFolder(Path.Combine(currentDirectory, "Plugins"), SearchOption.AllDirectories);
});
完整Program.cs代码如下:
class Program
{
static void Main(string[] args)
{
var currentDirectory = typeof(Program).GetAssembly().GetDirectoryPathOrNull();
// 设置工作目录. 保证工作在windows service时log文件存放目录正确
// 如果不设置, 工作在windows service时log文件将会存放在system32目录中
Directory.SetCurrentDirectory(currentDirectory); var services = new ServiceCollection();
IdentityRegistrar.Register(services); services.AddAbp<AbpZeroWinServiceModule>(options =>
{
//Configure Log4Net logging
options.IocManager.IocContainer.AddFacility<LoggingFacility>(
f => f.UseAbpLog4Net().WithConfig(Path.Combine(currentDirectory, $"log4net.config"))
); options.PlugInSources.AddFolder(Path.Combine(currentDirectory, "Plugins"), SearchOption.AllDirectories);
}); HostFactory.Run(x =>
{
x.Service<AbpZeroWinService>(s =>
{
s.ConstructUsing(name => new AbpZeroWinService());
s.WhenStarted((tc, hostControl) => tc.Start(hostControl));
s.WhenStopped((tc, hostControl) => tc.Stop(hostControl));
}); x.RunAsLocalSystem();
x.StartAutomatically(); x.SetDescription("ABP服务测试");
x.SetDisplayName("ABPTestService");
x.SetServiceName("ABPTestService");
});
}
}
- 设置工作目录
启动ABP. Windows service启动时会调用
s.ConstructUsing(name => new AbpZeroWinService());
, 因此我们在AbpZeroWinService
中启动ABP.- 创建
AbpZeroWinService
类继承自ServiceControl
, 在Start
中初始化AbpBootstrapper
, 同时在停止Stop
中销毁AbpBootstrapper
. 代码如下:
public class AbpZeroWinService : ServiceControl
{
private AbpBootstrapper _bootstrapper;
public bool Start(HostControl hostControl)
{
_bootstrapper = IocManager.Instance.Resolve<AbpBootstrapper>();
_bootstrapper.Initialize();
return true;
} public bool Stop(HostControl hostControl)
{
_bootstrapper.Dispose();
return true;
}
}
- 创建
quartz.net的配置
quartz.config
中必须使用AdoJobStore
类型,并且使用和Host一样的Quartz数据库连接,这样才能实现在host上添加任务,最终由windows service来执行任务。
(请在HostModule的PreInitialize
方法中禁用Job执行Configuration.BackgroundJobs.IsJobExecutionEnabled = false;
)运行前确保Quartz.net数据库已建立,如何建立请参考Quartz.net官方文档
以上如有错误的地方请大家指正! 如果更好的实现方式,也请分享一下。
最后给出WindowService项目的源码,Aspnet Zero的项目自行解决。
source code
最新文章
- Android性能优化
- Linux命令详解nice
- 【网络收集】MySql中IS NOT NULL与!=NULL的区别
- Android 通过广播启动另一个应用的Activity
- java获取计算机硬件参数
- logstash match
- 关于Java配置文件properties的学习
- raise()函数
- Spring MVC Json数据传递
- window.settimeout用法与window.setInterval用法的区别
- Python 项目实践一(外星人入侵)第一篇
- Kerberos原理
- Django admin组件源码流程
- CentOS 7.5 安装 Python3.7
- 【转】C++标准转换运算符reinterpret_cast
- 转://Linux MultiPath多路径软件实施说明
- vue项目打包后一片空白及资源引入的路径报错解决办法
- Python 调用 Redis API
- MySQL -- 全文检索
- 【linux系列】centos安装vsftp
热门文章
- 导出Telegram贴纸
- Linux cut 命令详解
- 更改docker默认存储路径操作(centos6版本)
- Java+MySQL企业级实训全套课程
- seaborn分类数据可视化:散点图|箱型图|小提琴图|lv图|柱状图|折线图
- OnePill本地保存用户的结构
- 【Django组件】WebSocket的简单实现
- 《谁说菜鸟不会数据分析》高清PDF全彩版|百度网盘免费下载|Python数据分析
- Java线程池ThreadPoolExecutor面试总结思维导图速记
- Blob分析之bottle.hdev