我与MEF合作很长一段时间,偶尔它会让我发疯。不知道它需要什么。
我有两个我们感兴趣的文件:
JobFactory:IJobFactory和SaferWatchProcessor:IJob
创建容器:
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没有任何东西,只有一种方法。有导出属性。
[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)
答案 0 :(得分:2)
好的,我认真思考。我认为发布我的发现会很有用。
我发生了什么,我从NuGet安装了MEF 2,新的轻量级MEF for 4.5和Windows商店。
我现有的所有库都是使用常规的旧MEF构建的
using System.ComponentModel.Composition
对于这个有问题的导入,ReSharper建议使用几个名称空间,并使用import using System.Composition
作为导出属性
不确定MEF 2有什么用处,但它不适用于常规MEF的现有库/出口,所以要小心!
答案 1 :(得分:1)
这是一个快速检查清单:
SaferWatchProcessor
类型的程序集物理复制到目录文件夹SaferWatchProcessor
类型确实导出Quartz.IJob
。当人们尝试导出由Visual Studio创建的空接口而不是引用真实的