提示

建议使用 JSON 持久格式来将数据存储在新项目的数据库中。 您还应该强烈考虑将 useProperties 设置为 true 以将键值限制为字符串。

Quartz.Serialization.Json 为使用 Json.NET 处理实际序列化过程的作业存储提供 JSON 序列化支持。

安装

您需要将 NuGet 包引用添加到使用 Quartz 的项目中。

  1. Install-Package Quartz.Serialization.Json

配置

经典的基于属性的配置

  1. var properties = new NameValueCollection
  2. {
  3. ["quartz.jobStore.type"] = "Quartz.Impl.AdoJobStore.JobStoreTX, Quartz",
  4. // "json" is alias for "Quartz.Simpl.JsonObjectSerializer, Quartz.Serialization.Json"
  5. ["quartz.serializer.type"] = "json"
  6. };
  7. ISchedulerFactory schedulerFactory = new StdSchedulerFactory(properties);

使用调度程序构建器进行配置

  1. var config = SchedulerBuilder.Create();
  2. config.UsePersistentStore(store =>
  3. {
  4. // it's generally recommended to stick with
  5. // string property keys and values when serializing
  6. store.UseProperties = true;
  7. store.UseGenericDatabase(dbProvider, db =>
  8. db.ConnectionString = "my connection string"
  9. );
  10. store.UseJsonSerializer();
  11. });
  12. ISchedulerFactory schedulerFactory = config.Build();

从二进制序列化迁移

现在有官方的迁移解决方案,因为每个设置都可能存在怪癖,但有一个适合您的方法。

  • 配置自定义序列化器,如下面的 MigratorSerializer 可以读取二进制序列化格式并写入 JSON 格式
  • 要么让系统在运行时逐渐迁移,要么创建一个程序,将所有相关的序列化资产加载并写回数据库

示例混合串行器

  1. public class MigratorSerializer : IObjectSerializer
  2. {
  3. private BinaryObjectSerializer binarySerializer;
  4. private JsonObjectSerializer jsonSerializer;
  5. public MigratorSerializer()
  6. {
  7. this.binarySerializer = new BinaryObjectSerializer();
  8. // you might need custom configuration, see sections about customizing
  9. // in documentation
  10. this.jsonSerializer = new JsonObjectSerializer();
  11. }
  12. public T DeSerialize<T>(byte[] data) where T : class
  13. {
  14. try
  15. {
  16. // Attempt to deserialize data as JSON
  17. var result = this.jsonSerializer.DeSerialize<T>(data);
  18. return result;
  19. }
  20. catch (JsonReaderException)
  21. {
  22. // Presumably, the data was not JSON, we instead use the binary serializer
  23. return this.binarySerializer.DeSerialize<T>(data);
  24. }
  25. }
  26. public void Initialize()
  27. {
  28. this.binarySerializer.Initialize();
  29. this.jsonSerializer.Initialize();
  30. }
  31. public byte[] Serialize<T>(T obj) where T : class
  32. {
  33. return this.jsonSerializer.Serialize<T>(obj);
  34. }
  35. }

自定义 JSON.NET

如果需要自定义 JSON.NET 设置,则需要继承自定义实现并覆盖 CreateSerializerSettings

  1. class CustomJsonSerializer : JsonObjectSerializer
  2. {
  3. protected override JsonSerializerSettings CreateSerializerSettings()
  4. {
  5. var settings = base.CreateSerializerSettings();
  6. settings.Converters.Add(new MyCustomConverter());
  7. return settings;
  8. }
  9. }

然后配置它使用

  1. store.UseSerializer<CustomJsonSerializer>();
  2. // or
  3. "quartz.serializer.type" = "MyProject.CustomJsonSerializer, MyProject"

自定义日历序列化

如果您实现了自定义日历,则需要为其实现 ICalendarSerializer。 有一个方便的基类 CalendarSerializer,您可以使用它来获得强类型体验。

自定义日历和序列化程序

  1. [Serializable]
  2. class CustomCalendar : BaseCalendar
  3. {
  4. public CustomCalendar()
  5. {
  6. }
  7. // binary serialization support
  8. protected CustomCalendar(SerializationInfo info, StreamingContext context) : base(info, context)
  9. {
  10. SomeCustomProperty = info?.GetBoolean("SomeCustomProperty") ?? true;
  11. }
  12. public bool SomeCustomProperty { get; set; } = true;
  13. // binary serialization support
  14. public override void GetObjectData(SerializationInfo info, StreamingContext context)
  15. {
  16. base.GetObjectData(info, context);
  17. info?.AddValue("SomeCustomProperty", SomeCustomProperty);
  18. }
  19. }
  20. // JSON serialization support
  21. class CustomCalendarSerializer : CalendarSerializer<CustomCalendar>
  22. {
  23. protected override CustomCalendar Create(JObject source)
  24. {
  25. return new CustomCalendar();
  26. }
  27. protected override void SerializeFields(JsonWriter writer, CustomCalendar calendar)
  28. {
  29. writer.WritePropertyName("SomeCustomProperty");
  30. writer.WriteValue(calendar.SomeCustomProperty);
  31. }
  32. protected override void DeserializeFields(CustomCalendar calendar, JObject source)
  33. {
  34. calendar.SomeCustomProperty = source["SomeCustomProperty"]!.Value<bool>();
  35. }
  36. }

配置自定义日历序列化程序

  1. var config = SchedulerBuilder.Create();
  2. config.UsePersistentStore(store =>
  3. {
  4. store.UseJsonSerializer(json =>
  5. {
  6. json.AddCalendarSerializer<CustomCalendar>(new CustomCalendarSerializer());
  7. });
  8. });
  9. // or just globally which is what above code calls
  10. JsonObjectSerializer.AddCalendarSerializer<CustomCalendar>(new CustomCalendarSerializer());