4

我与 MEF 合作了很长时间,有时它会让我发疯。不知道它需要什么。

我有 2 个我们感兴趣的文件:

  1. 我的 EXE 有 2 个类:

JobFactory : IJobFactory 和 SaferWatchProcessor : IJob

  1. 具有这些接口定义的 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 那里什么都没有,只有一种方法。具有导出属性。

[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 个项目)

我尝试将其设置为单个 Import 并收到以下错误:

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)
4

2 回答 2

2

好吧,我想通了。我认为发布我的发现会很有用。

发生的事情是我从 NuGet 安装了 MEF 2、用于 4.5 的新轻量级 MEF 和 Windows 商店。

我所有现有的库都是用常规的旧 MEF 构建的 using System.ComponentModel.Composition,对于这个有问题的导入,ReSharper 建议了几个命名空间,我将其import using System.Composition用于 Export 属性

不确定 MEF 2 有什么好处,但它不适用于针对常规 MEF 的现有库/导出,所以要小心!

于 2013-08-21T19:48:08.370 回答
1

这是一个快速检查清单:

  • 确保具有SaferWatchProcessor类型的程序集物理复制到目录文件夹
  • 确保相应的程序集是最新的并且在目录文件夹中具有正确的时间戳
  • 确保该SaferWatchProcessor类型真正出口Quartz.IJob。当人们试图导出由 Visual Studio 创建的空界面而不是引用真实的界面时,这是一个常见的错误
于 2013-08-21T19:19:03.370 回答