Revert back to using InvocationData, as the following functionality has been lost, but is already handled by Hangfire
- Overloaded method calls e.g. Console.WriteLine(String) vs Console.WriteLine(Int32) Console.WriteLine(Boolean) - Generic method calls - Nullable parameters in method calls - Special handling of CancellationToken arguments during serialization/deserialization
This commit is contained in:
@@ -1,54 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
#if !NET45
|
||||
using Microsoft.Extensions.DependencyModel;
|
||||
#endif
|
||||
|
||||
namespace Hangfire.Raven
|
||||
{
|
||||
/// <summary>
|
||||
/// Helper class for getting assemblies
|
||||
/// </summary>
|
||||
public static class Assemblies
|
||||
{
|
||||
/// <summary>
|
||||
/// Get all loaded assemblies
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public static IEnumerable<Assembly> Get()
|
||||
{
|
||||
#if NET45
|
||||
return AppDomain.CurrentDomain.GetAssemblies().Where(a => a != null);
|
||||
#else
|
||||
return (from compilationLibrary in DependencyContext.Default.CompileLibraries
|
||||
where compilationLibrary.Name.Contains(typeof(Assemblies).Namespace)
|
||||
select Assembly.Load(new AssemblyName(compilationLibrary.Name)))
|
||||
.ToList();
|
||||
#endif
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get class by name within an assembly
|
||||
/// </summary>
|
||||
/// <param name="assembly">Assembly</param>
|
||||
/// <param name="type">Name of type</param>
|
||||
/// <returns></returns>
|
||||
public static Type GetClass(Assembly assembly, string type)
|
||||
{
|
||||
return (from t in assembly.GetTypes()
|
||||
where t.FullName == type //&& !t.IsAbstract && t.IsClass
|
||||
select t).FirstOrDefault();
|
||||
}
|
||||
|
||||
public static string GetAssemblyName(MemberInfo value)
|
||||
{
|
||||
#if NET45
|
||||
return value.DeclaringType.Assembly.GetName().Name;
|
||||
#else
|
||||
return value.DeclaringType.GetTypeInfo().Assembly.GetName().Name;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,5 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using Hangfire.Common;
|
||||
using Hangfire.Storage;
|
||||
using Hangfire.Storage.Monitoring;
|
||||
@@ -15,31 +13,9 @@ namespace Hangfire.Raven.Entities
|
||||
this.Parameters = new Dictionary<string, string>();
|
||||
this.History = new List<StateHistoryDto>();
|
||||
}
|
||||
public class JobWrapper
|
||||
{
|
||||
public IEnumerable<object> Arguments { get; set; }
|
||||
public Type Type { get; set; }
|
||||
public MethodInfo Method { get; set; }
|
||||
|
||||
public Job GetJob()
|
||||
{
|
||||
return new Job(this.Type, this.Method, this.Arguments.ToArray());
|
||||
}
|
||||
|
||||
public static JobWrapper Create(Job job)
|
||||
{
|
||||
var toReturn = new JobWrapper();
|
||||
|
||||
toReturn.Arguments = job.Args;
|
||||
toReturn.Method = job.Method;
|
||||
toReturn.Type = job.Type;
|
||||
|
||||
return toReturn;
|
||||
}
|
||||
}
|
||||
|
||||
public string Id { get; set; }
|
||||
public JobWrapper Job { get; set; }
|
||||
public InvocationData InvocationData { get; set; }
|
||||
public IDictionary<string, string> Parameters { get; set; }
|
||||
public DateTime CreatedAt { get; set; }
|
||||
|
||||
|
||||
@@ -77,11 +77,13 @@ namespace Hangfire.Raven
|
||||
parameters.ThrowIfNull("parameters");
|
||||
|
||||
using (var repository = _storage.Repository.OpenSession()) {
|
||||
var invocationData = InvocationData.Serialize(job);
|
||||
|
||||
var guid = Guid.NewGuid().ToString();
|
||||
|
||||
var ravenJob = new RavenJob {
|
||||
Id = Repository.GetId(typeof(RavenJob), guid),
|
||||
Job = JobWrapper.Create(job),
|
||||
InvocationData = invocationData,
|
||||
CreatedAt = createdAt,
|
||||
Parameters = parameters
|
||||
};
|
||||
@@ -107,12 +109,23 @@ namespace Hangfire.Raven
|
||||
return null;
|
||||
}
|
||||
|
||||
var job = jobData.Job.GetJob();
|
||||
Job job = null;
|
||||
JobLoadException loadException = null;
|
||||
|
||||
try
|
||||
{
|
||||
job = jobData.InvocationData.Deserialize();
|
||||
}
|
||||
catch (JobLoadException ex)
|
||||
{
|
||||
loadException = ex;
|
||||
}
|
||||
|
||||
return new JobData {
|
||||
Job = job,
|
||||
State = jobData.StateData?.Name,
|
||||
CreatedAt = jobData.CreatedAt
|
||||
CreatedAt = jobData.CreatedAt,
|
||||
LoadException = loadException
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,133 +0,0 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using Raven.Imports.Newtonsoft.Json;
|
||||
using Raven.Imports.Newtonsoft.Json.Linq;
|
||||
|
||||
namespace Hangfire.Raven
|
||||
{
|
||||
/// <summary>
|
||||
/// Base class for Raven Json Converters
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
public abstract class RavenJsonConverterBase<T>
|
||||
: JsonConverter
|
||||
{
|
||||
public RavenJsonConverterBase()
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Read Json and convert to T
|
||||
/// </summary>
|
||||
/// <param name="type"></param>
|
||||
/// <param name="value">Object to convert</param>
|
||||
/// <param name="serializer">JsonSerializer</param>
|
||||
/// <returns>Object</returns>
|
||||
protected abstract T Read(Type type, object value, JsonSerializer serializer);
|
||||
|
||||
/// <summary>
|
||||
/// Write Json and convert T to text
|
||||
/// </summary>
|
||||
/// <param name="value">Input</param>
|
||||
/// <returns>Input as text</returns>
|
||||
protected abstract object Write(T value, JsonSerializer serializer);
|
||||
|
||||
/// <summary>
|
||||
/// Overriding the CanConvert of JsonConvert
|
||||
/// </summary>
|
||||
/// <param name="type"></param>
|
||||
/// <returns></returns>
|
||||
public override bool CanConvert(Type type) => typeof(T).IsAssignableFrom(type);
|
||||
|
||||
/// <summary>
|
||||
/// Overriding the ReadJson of JsonConvert
|
||||
/// </summary>
|
||||
/// <param name="reader"></param>
|
||||
/// <param name="type"></param>
|
||||
/// <param name="existingValue"></param>
|
||||
/// <param name="serializer"></param>
|
||||
/// <returns></returns>
|
||||
public override object ReadJson(JsonReader reader, Type type, object existingValue, JsonSerializer serializer)
|
||||
{
|
||||
T toReturn;
|
||||
|
||||
switch (reader.TokenType) {
|
||||
case JsonToken.StartArray:
|
||||
toReturn = Read(type, JArray.Load(reader), serializer);
|
||||
break;
|
||||
case JsonToken.StartObject:
|
||||
toReturn = Read(type, JObject.Load(reader), serializer);
|
||||
break;
|
||||
default:
|
||||
toReturn = Read(type, reader.Value, serializer);
|
||||
break;
|
||||
}
|
||||
|
||||
return toReturn;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Overriding the WriteJson of JsonConvert
|
||||
/// </summary>
|
||||
/// <param name="writer"></param>
|
||||
/// <param name="value"></param>
|
||||
/// <param name="serializer"></param>
|
||||
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
|
||||
{
|
||||
serializer.Serialize(writer, Write((T)value, serializer));
|
||||
}
|
||||
}
|
||||
|
||||
public class RavenJsonMethodConverter
|
||||
: RavenJsonConverterBase<MethodInfo>
|
||||
{
|
||||
protected override MethodInfo Read(Type type, object value, JsonSerializer serializer)
|
||||
{
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
var splitted = value.ToString().Split(';');
|
||||
|
||||
if (splitted.Count() == 3) {
|
||||
var assembly = Assemblies.Get().Where(a => a.GetName().Name == splitted[0]).First();
|
||||
var assemblyClass = Assemblies.GetClass(assembly, splitted[1]);
|
||||
|
||||
if (assemblyClass != null) {
|
||||
return assemblyClass.GetMethod(splitted[2]);
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
protected override object Write(MethodInfo value, JsonSerializer serializer) => $"{value.DeclaringType.GetTypeInfo().Assembly.GetName().Name};{value.DeclaringType.FullName};{value.Name}";
|
||||
}
|
||||
|
||||
public class RavenJsonPropertyConverter
|
||||
: RavenJsonConverterBase<PropertyInfo>
|
||||
{
|
||||
protected override PropertyInfo Read(Type type, object value, JsonSerializer serializer)
|
||||
{
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
var splitted = value.ToString().Split(';');
|
||||
|
||||
if (splitted.Count() == 3) {
|
||||
var assembly = Assemblies.Get().Where(a => a.GetName().Name == splitted[0]).First();
|
||||
var assemblyType = Assemblies.GetClass(assembly, splitted[1]);
|
||||
|
||||
if (assemblyType != null) {
|
||||
return assemblyType.GetProperty(splitted[2]);
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
protected override object Write(PropertyInfo value, JsonSerializer serializer) => $"{value.DeclaringType.GetTypeInfo().Assembly.GetName().Name};{value.DeclaringType.FullName};{value.Name}";
|
||||
}
|
||||
}
|
||||
@@ -7,7 +7,6 @@ using Raven.Abstractions.Data;
|
||||
using Raven.Client;
|
||||
using Raven.Client.Document;
|
||||
using Raven.Client.Indexes;
|
||||
using Raven.Imports.Newtonsoft.Json;
|
||||
|
||||
namespace Hangfire.Raven
|
||||
{
|
||||
@@ -56,25 +55,13 @@ namespace Hangfire.Raven
|
||||
|
||||
if (!string.IsNullOrEmpty(_config.ConnectionStringName)) {
|
||||
_documentStore = new DocumentStore {
|
||||
ConnectionStringName = _config.ConnectionStringName,
|
||||
Conventions = new DocumentConvention() {
|
||||
CustomizeJsonSerializer = delegate (JsonSerializer input) {
|
||||
input.Converters.Add(new RavenJsonPropertyConverter());
|
||||
input.Converters.Add(new RavenJsonMethodConverter());
|
||||
}
|
||||
}
|
||||
ConnectionStringName = _config.ConnectionStringName
|
||||
};
|
||||
} else {
|
||||
_documentStore = new DocumentStore {
|
||||
Url = _config.ConnectionUrl,
|
||||
ApiKey = _config.ApiKey,
|
||||
DefaultDatabase = _config.Database,
|
||||
Conventions = new DocumentConvention() {
|
||||
CustomizeJsonSerializer = delegate (JsonSerializer input) {
|
||||
input.Converters.Add(new RavenJsonPropertyConverter());
|
||||
input.Converters.Add(new RavenJsonMethodConverter());
|
||||
}
|
||||
}
|
||||
DefaultDatabase = _config.Database
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -285,7 +285,7 @@ namespace Hangfire.Raven.Storage
|
||||
return new JobDetailsDto {
|
||||
CreatedAt = job.CreatedAt,
|
||||
ExpireAt = repository.Advanced.GetExpire(job),
|
||||
Job = job.Job.GetJob(),
|
||||
Job = DeserializeJob(job.InvocationData),
|
||||
History = job.History,
|
||||
Properties = job.Parameters
|
||||
};
|
||||
@@ -399,7 +399,7 @@ namespace Hangfire.Raven.Storage
|
||||
let stateData = job.StateData.Data != null
|
||||
? new Dictionary<string, string>(job.StateData.Data, StringComparer.OrdinalIgnoreCase)
|
||||
: null
|
||||
let dto = selector(job, job.Job.GetJob(), stateData)
|
||||
let dto = selector(job, DeserializeJob(job.InvocationData), stateData)
|
||||
select new KeyValuePair<string, TDto>(job.Id.Split(new char[] { '/' }, 2)[1], dto);
|
||||
|
||||
return new JobList<TDto>(result);
|
||||
|
||||
Reference in New Issue
Block a user