我有几个Job项目,每个项目都声明了一个作业。声明每个作业都从IJob<IJobPayload>
接口继承。我有另一个不引用任何这些项目的应用程序,但必须能够使用它们。为此,我正在扫描目录以查找与已知命名约定匹配的所有项目。然后我做了一些操作并尝试在Unity中注册它们。
var container = UnityConfig.GetConfiguredContainer();
var path = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
var files = Directory.GetFiles(path, "QueueApp.Job.*.dll");
var allAssemblies = files.Select(Assembly.LoadFile).ToList();
var jobAssemblies = AllClasses.FromAssemblies(allAssemblies);
var jobTypes = jobAssemblies.Where(type => typeof(IJob).IsAssignableFrom(type) && type.IsClass);
container.RegisterTypes(
jobTypes,
WithMappings.FromAllInterfaces,
WithName.Default,
WithLifetime.ContainerControlled);
files
集合显示找到6个DLL
allAssemblies
集合显示6个组件
jobAssemblies
集合显示4个项目,其中没有一个是基于IJob的类!
jobTypes
是空的!
我没有看到我做错了什么。
让我从底部构建这个:
public interface IJob<TPayload> : IJob where TPayload : IJobPayload
{
JobType JobType { get; }
JobInfoPayload JobInfo { get; }
TPayload Payload { get; set; }
string PayloadAsString { get; set; }
string Execute(IServerFilter jobContext, string payload, IJobCancellationToken cancellationToken);
bool CachePut();
bool CacheGet();
bool CacheExists();
}
基类:
public class BaseJob<TPayload> : IEventSource where TPayload : IJobPayload
{
protected internal IJobExecutor<TPayload>[] Executors;
public JobInfoPayload JobInfo => Payload.JobInfo;
public TPayload Payload { get; set; }
public string PayloadAsString
{
get { return JsonConvert.SerializeObject(Payload); }
set { Payload = JsonConvert.DeserializeObject<TPayload>(value); }
}
protected internal readonly List<IEvent> Events = new List<IEvent>();
public string Execute(IServerFilter jobContext, IJobCancellationToken cancellationToken)
{
// TODO: setup bus handler definitions here...
while (Payload.JobInfo.JobStatus != JobStatus.Done)
{
var jobStrategy = new JobExecutorStrategy<TPayload>(Executors);
Payload = jobStrategy.Execute(Payload);
if (Payload.JobInfo.JobStatus == JobStatus.Handoff)
break;
}
return PayloadAsString;
}
public bool CachePut()
{
}
public bool CacheGet()
{
}
public bool CacheExists()
{
}
public IEnumerable<IEvent> GetEvents()
{
return Events;
}
public void Clear()
{
Events.Clear();
}
}
示例作业类:
public class JobPingPong : BaseJob<JobPingPong.PayloadModel>, IJob<JobPingPong.PayloadModel>
{
public JobType JobType => JobType.AdHoc;
/// <summary>
/// Additional fields for the PAYLOAD required to run job...
/// </summary>
public class PayloadModel : MinimumPayload
{
public string[] Tokens { get; set; }
public int GenericIntId { get; set; }
public string GenericStringId { get; set; }
}
public JobPingPong()
{
Executors = new IJobExecutor<PayloadModel>[]
{
new Initialize(this),
new Processing(this),
new Complete(this),
new ExtComplete(this),
new ExtError(this),
new Error(this)
};
}
/// <summary>
/// Overrides the base class method so we can decorate with a specific set of attributes: DisableConcurrentExecution, QueueName
/// </summary>
/// <seealso cref="https://github.com/HangfireIO/Hangfire/issues/245"/>
/// <param name="jobContext"></param>
/// <param name="payload"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
[DisableConcurrentExecution(30)]
[Queue("serial")]
public string Execute(IServerFilter jobContext, string payload, IJobCancellationToken cancellationToken)
{
PayloadAsString = payload;
return base.Execute(jobContext, cancellationToken);
}
}
当我尝试将其纳入Unity时,我所看到的只是子类JobPingPong.Payload
,但找不到类JobPingPong
。我错过了什么明显的事情?我不需要Unity中的任何IJobPayload
类,只需要基于IJob
的类。
附加信息:我添加了此代码,看看我是否可以到达我想要的位置。虽然它注册了IJob,但它没有注册为具体类。
var dependencies = Directory.GetFiles(@"D:\...\Development\QueueApp\Source\QueueApp.Job.TestPingPong\bin\Debug", "QueueApp.Job.*.dll");
var pluginMappings = new Dictionary<Type, Type>();
//Load Dependency Assemblies
foreach (string fileName in dependencies)
{
if (fileName.Contains("Batc.QueueApp.Job.Core")) continue;
var pluginAssembly = Assembly.LoadFrom(fileName);
var pluginTypeList = pluginAssembly.GetTypes();
foreach (var pluginType in pluginTypeList)
{
if (!pluginType.IsPublic || pluginType.IsAbstract) continue;
//Gets a type object of the interface we need the plugins to match
var typeInterfaces = pluginType.GetInterfaces();
foreach (var typeInterface in typeInterfaces)
{
if (pluginMappings.ContainsKey(typeInterface)) continue;
pluginMappings.Add(typeInterface, pluginType);
}
}
}
//Web API resolve dependencies with Unity
var container = Dependency.UnityConfig.GetConfiguredContainer();
pluginMappings.ForEach(mapping => container.RegisterType(mapping.Key, mapping.Value));