【问题标题】:No exports were found that match the constraint: Issues getting my wpf application to work with MEF未找到与约束匹配的导出:问题让我的 wpf 应用程序与 MEF 一起工作
【发布时间】:2019-11-27 16:37:13
【问题描述】:

我正在开发一个 WPF 应用程序,我想使用 MEF (Manageable Extensibility Framework) 构建我的项目。但问题是当我尝试运行我的应用程序时出现此错误:

未找到与约束匹配的导出:ContractName MyFooPluginA 必需的TypeIdentity namespace.of.my.core.project.IFooPlugin

这是我继续创建的内容

相同的概念适用于所有 IBarPlugin 类型的插件项目。以下是我如何设置我的第一个插件项目:

FooView.xaml.cs

    /// <summary>
    /// Interaction logic for FooView.xaml
    /// </summary>
    [Export(typeof(IFooPlugin)), PartCreationPolicy(CreationPolicy.Any)]
    [ExportMetadata("Name", "MyFooPluginA")]
    public partial class FooView: UserControl, IFooPlugin
    {
        [ImportingConstructor]
        public FooView(FooViewModel viewModel) //we initialize the view first, then the view model
        {
            InitializeComponent();

            DataContext = viewModel;
        }

    }

FooViewModel:

[Export]
public class FooViewModel
{
  [ImportingConstructor]
  public FooViewModel(...) //Contains parameters for dependency injections
  {
    //doing some work here
  }
}

最后在主应用程序视图模型中,我正在加载插件:

public class MainAppViewModel 
{  
        /// <summary>
        /// If one plugin of type IFooPlugin is found then it is loaded in this property
        /// </summary>
        public IFooPlugin FooPluginView
        {
            get
            {
                return _fooPluginView;
            }
            set
            {
                _fooPluginView= value;
                RaisePropertyChanged(nameof(FooPluginView));
            }
        }    
        private IFooPlugin _fooPluginView;

        /// <summary>
        /// Stores the catalog of all exported dlls
        /// </summary>
        private AggregateCatalog catalog;

        /// <summary>
        /// Stores the catalog information and all its parts
        /// </summary>
        private CompositionContainer Container;

        public MainAppViewModel()
        {
          InitPlugin();//first thing I want it to do

          if (someConditon == true)
          {
            FooPluginView = Container.GetExport<IFooPlugin>("MyFooPluginA").Value;
          }
          else
          {
            FooPluginView = Container.GetExport<IFooPlugin>("MyFooPluginA").Value;
          }
       }

       private void InitPlugin()
       {
            //First create a catalog of exports
            //It can be TypeCatalog(typeof(ISomeView), typeof(SomeOtherImportType)) 
            //to search for all exports by specified types
            //DirectoryCatalog(pluginsPath, "App*.dll") to search specified directories
            //and matching specified file name
            //An aggregate catalog that combines multiple catalogs
            catalog = new AggregateCatalog();

            //Here we add all the parts found in all assemblies in directory of executing assembly directory
            //with file name matching Plugin*.dll
            string pluginsPath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
            catalog.Catalogs.Add(new DirectoryCatalog(pluginsPath, "*Plugin.dll"));

            //also we add to a search path a subdirectory plugins
            pluginsPath = Path.Combine(pluginsPath, "Plugins");

            catalog.Catalogs.Add(new DirectoryCatalog(pluginsPath, "*Plugin.dll"));

            //Create the CompositionContainer with the parts in the catalog.
            Container = new CompositionContainer(catalog);

            //Fill the imports of this object
            //finds imports and fills in all preperties decorated
            //with Import attribute in this instance
            Container.ComposeParts(this);
     }
 }

【问题讨论】:

    标签: c# wpf mef


    【解决方案1】:

    恐怕这可能不是您想要的确切答案,但据我所知 [ExportMetadata] 的属性值并未设置 ContractName。它的值被分配为元数据。所以,你可以改变

    FooPluginView = Container.GetExport&lt;IFooPlugin&gt;("MyFooPluginA").Value;

    FooPluginView = Container.GetExports&lt;IFooPlugin, IDictionary&lt;string, object&gt;&gt;().Where(x =&gt; (string)x.Metadata["Name"] == "MyFooPluginA").FirstOrDefault().Value;

    或类似的。另外,您似乎没有将参数传递给 ImportingConstructor。我尝试了在MEF Constructor Injection 中对您的情况进行解释的解决方案,例如

    [ImportingConstructor]
    public UserControl1([Import("DI")]FooViewModel viewModel)
    
    Container.ComposeExportedValue("DI",new FooViewModel(null));
    FooPluginView = Container.GetExports<IFooPlugin, IDictionary<string, object>>().Where(x => (string)x.Metadata["Name"] == "MyFooPluginA").FirstOrDefault().Value;
    
    

    它在我的环境中运行良好。希望对您有所帮助。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-02-17
      • 1970-01-01
      • 2017-03-06
      • 2022-10-06
      • 2011-12-13
      • 1970-01-01
      • 2014-07-13
      相关资源
      最近更新 更多