私は長い間 MEF と仕事をしていますが、ときどき気が狂いそうになります。何が必要なのかわからない。
関心のあるファイルが 2 つあります。
- 2つのクラスを持つ私のEXE:
JobFactory : IJobFactory および SaferWatchProcessor : IJob
- これらのインターフェース定義を持つ Quartz.net DLL
コンテナの作成:
var aggregateCatalog = new AggregateCatalog(
new DirectoryCatalog(".", "*.dll"),
new DirectoryCatalog(".", "*.exe"));
Bootstrapper.CompositionContainer = new CompositionContainer(aggregateCatalog, true);
カタログには JobFactory が含まれるようになりましたが、SaferWatchProcessor はありません。なんで?
クラスは次のとおりです。
[Export(typeof(IJob))]
public class SaferWatchProcessor : IJob
{
public void Execute(IJobExecutionContext context)
{
Debug.WriteLine("SaferWatchProcessor.Execute");
}
}
SaferWatchProcessor には何もありません。メソッドは 1 つだけです。エクスポート属性を持つ。
[Export(typeof(IJobFactory))]
public class JobFactory : IJobFactory
{
[ImportMany(typeof(IJob))]
public List<IJob> Jobs { get; private set; }
public virtual IJob NewJob(TriggerFiredBundle bundle, IScheduler scheduler)
{
IJobDetail jobDetail = bundle.JobDetail;
Type jobType = jobDetail.JobType;
try
{
Debug.WriteLine("IDATT.WindowsService.JobFactory - creating job instance");
return this.Jobs.First();
}
catch (Exception e)
{
var se = new SchedulerException(string.Format(CultureInfo.InvariantCulture, "Problem instantiating class '{0}'", jobDetail.JobType.FullName), e);
throw se;
}
}
public virtual void ReturnJob(IJob job)
{
}
}
JobFactory には ImportMany があります (これは失敗しませんが、アイテムは 0 です)
単一のインポートとして設定しようとしましたが、次のエラーが発生していました:
System.ComponentModel.Composition Warning: 1 : The ComposablePartDefinition 'IDATT.WindowsService.JobFactory' has been rejected. The composition remains unchanged. The changes were rejected because of the following error(s): The composition produced a single composition error. The root cause is provided below. Review the CompositionException.Errors property for more detailed information.
1) No exports were found that match the constraint:
ContractName Quartz.IJob
RequiredTypeIdentity Quartz.IJob
Resulting in: Cannot set import 'IDATT.WindowsService.JobFactory.Jobs (ContractName="Quartz.IJob")' on part 'IDATT.WindowsService.JobFactory'.
Element: IDATT.WindowsService.JobFactory.Jobs (ContractName="Quartz.IJob") --> IDATT.WindowsService.JobFactory --> DirectoryCatalog (Path=".")
A first chance exception of type 'System.InvalidOperationException' occurred in IDATT.WindowsService.exe
何も問題はないように見えますが、なぜ IJob をインポートしたくないのでしょうか?
編集:
すべての IJob 定義を削除し、プレーンなエクスポート/インポートを使用して、MEF のデバッグを追加しました。まだ問題があり、ここにエラーがあります:
[Part] IDATT.WindowsService.JobFactory from: DirectoryCatalog (Path="C:\CodeWorkspace\IdattLC\ClientServerCode\IDATT.WindowsService\bin\Debug\")
[Primary Rejection]
[Export] IDATT.WindowsService.JobFactory (ContractName="Quartz.Spi.IJobFactory")
[Import] IDATT.WindowsService.JobFactory.SaferWatchProcessor (ContractName="IDATT.WindowsService.Jobs.SaferWatchProcessor")
[Exception] System.ComponentModel.Composition.ImportCardinalityMismatchException: No exports were found that match the constraint:
ContractName IDATT.WindowsService.Jobs.SaferWatchProcessor
RequiredTypeIdentity IDATT.WindowsService.Jobs.SaferWatchProcessor
at System.ComponentModel.Composition.Hosting.ExportProvider.GetExports(ImportDefinition definition, AtomicComposition atomicComposition)
at System.ComponentModel.Composition.Hosting.ExportProvider.GetExports(ImportDefinition definition)
at Microsoft.ComponentModel.Composition.Diagnostics.CompositionInfo.AnalyzeImportDefinition(ExportProvider host, IEnumerable`1 availableParts, ImportDefinition id)