使用特定接口时MEF组合导入问题

时间:2013-08-21 19:02:29

标签: c# .net mef

我与MEF合作很长一段时间,偶尔它会让我发疯。不知道它需要什么。

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

  1. 我的EXE有两个班级:
  2. JobFactory:IJobFactory和SaferWatchProcessor:IJob

    1. 具有这些接口定义的Quartz.net DLL
    2. 创建容器:

      var aggregateCatalog = new AggregateCatalog(
                      new DirectoryCatalog(".", "*.dll"),
                      new DirectoryCatalog(".", "*.exe"));
      
                  Bootstrapper.CompositionContainer = new CompositionContainer(aggregateCatalog, true);
      

      目录现在有JobFactory但没有SaferWatchProcessor。为什么呢?

      enter image description here

      这是课程:

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

2 个答案:

答案 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创建的空接口而不是引用真实的
  • 时,这是一个常见的错误