【问题标题】:Can you hydrate a static property using MEF?您可以使用 MEF 水合静态属性吗?
【发布时间】:2026-01-31 09:05:01
【问题描述】:

我可以在类的静态构造函数中水合它吗?

public class Connect:IDTExtensibility2, IDTCommandTarget
  static Connect()
    {
        //hydrate static properties?
    }
    [Import]
    public static Action<ProjectLogicChecks> Display { get; set; }

[Export(typeof(Action<ProjectLogicChecks>))]
    private static void DisplayResults( CheckProcesses _checkResults)
{
    MessageBox.Show(_checkResults.ProjectLogicCheck.AssemblyName + " has problems=" +
                    _checkResults.ProjectLogicCheck.HasProblems);
}

【问题讨论】:

  • “Hydrate”是 hibernate 的一个术语,意思是反序列化,即将数据转换回域对象。您的意思是“初始化”吗?
  • @Wim - 我认为它的意思是用它的值填充一个类。
  • @Wim - 你能链接任何表示水合必须反序列化的资源吗?我在谷歌上没有想出很多看起来不符合我定义的东西。
  • 第 1 个链接谈到了从数据库中补水。接下来的 4 个链接中的 3 个要么谈论“从其他来源补水”,要么不提及任何来源类型。您是查看搜索结果还是只是链接某些内容?

标签: .net mef static-methods


【解决方案1】:

不,MEF 不支持静态导入。

【讨论】:

  • +1 从容器中提取值并将其填充到静态属性中不是导入。使用容器的全部意义在于它负责自动注入依赖项。如果你要自己做,你还不如把容器完全扔掉。可重用、可单元测试、松散耦合的代码应避免使用静态成员。静态成员将所有东西粘在一个大泥球中。
  • @Wim - Visual Studio 将其称为导入,没有对提供插件和组合工作的代码的引用。仅仅因为在某些情况下使用静态是一种不好的做法并不意味着它不是 MEF。另外,我有 TypeMock,静态成员是可单元测试的。那你想在这里说什么?
  • @Maslow 您放在静态成员上的 Import 属性没有做任何事情。您可以删除该属性,您的代码将以相同的方式工作。这就是为什么我们不认为它是进口的。
  • @Daniel - 好的......那么我应该使用什么术语?以及导入应该如何工作?我的目标是用 MEF 水合静态属性,我实现了它。我在我的问题中遗漏了哪些技术细节/措辞来说明这一点?
  • @wim - 我的问题是关于填充属性而不是关于“导入”。所以我错误地使用导入属性与问题无关。您对答案的 +1 仍然是琐碎且离题的。
【解决方案2】:

这比我想象的要容易。

 static Connect()
    {
        var batch = new CompositionBatch( );
        CompositionContainer container;
        var reflectionCatalog = new AssemblyCatalog(System.Reflection.Assembly.GetExecutingAssembly( ));

        var extensionPath = System.IO.Path.Combine(Environment.CurrentDirectory, "extensions");
        if (System.IO.Directory.Exists(extensionPath))
        {
            var directoryCatalog = new DirectoryCatalog(extensionPath);
            var defaultCatalogEp = new CatalogExportProvider(reflectionCatalog);
            container=new CompositionContainer(directoryCatalog, defaultCatalogEp);
            defaultCatalogEp.SourceProvider=container;
        }
        else
            container = new CompositionContainer(reflectionCatalog);

        container.Compose(batch);
 //Setting a static property
        Display=container.GetExportedValue<Action<IEnumerable< ProjectLogicChecks>>>( );
    }

将类型更改为Action&lt;IEnumerable&lt;ProjectLogicChecks&gt;&gt;,以便我可以显示多个项目或整个解决方案的结果,而不仅仅是一个。

我按照this 文章获取静态属性集,然后在this 提供本地默认值以防不存在扩展。

【讨论】:

  • 这是一个丑陋的解决方案。使用 MEF,您应该不需要静态的东西。您可以使用共享的部件创建策略导入某些内容,它的行为是静态的。
【解决方案3】:

您可以使用 [ImportingConstructor] 并在构造函数中设置静态属性。

private static RandomService Random { get; set; }  
[ImportingConstructor] 
public ClientViewModel(RandomService random)
 {   
 Random = random; 
} 

只是不要将其设置为静态字段。

【讨论】: