在 MEF 中组合零件后自动调用方法

发布于 2024-12-07 05:25:20 字数 48 浏览 0 评论 0原文

有没有办法指定在组成部分后自动调用方法?该方法可以在组合部分或进行组合的类中调用。

Is there a way to specify that a method gets called automatically after a part has been composed? The method could be called on the composed part or in the class doing the composition.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

但可醉心 2024-12-14 05:25:20

是的。如果您的类实现 IPartImportsSatisfiedNotification 接口,则MEF 容器将在正确的时间调用 OnImportsSatisfied

Yes. If your class implements the IPartImportsSatisfiedNotification interface, then the MEF container will call OnImportsSatisfied at the right time.

我是男神闪亮亮 2024-12-14 05:25:20

采用这种方法将在您的类中引入时间耦合 - 它将依赖于一些外部人员以正确的顺序调用方法才能正常工作。

时间耦合是一种主要代码味道 - 它使类的重用和理解变得更加困难。 (请记住,六个月后需要从头开始阅读和理解代码的开发人员就是您自己。)

相反,您的类应该负责它自己的初始化 - 它不应该依赖在外面的聚会上。

如果需要从构造函数推迟某些步骤,一种方法是将这些步骤移至私有方法中,然后向每个适当的公共方法添加一个保护步骤,以确保初始化完成。

public class Example 
{
    public Example()
    {
        // Constructor
    }

    public void Open()
    {
        EnsureInitialized();
        ...
    }

    private void EnsureInitialized()
    {
        if (!mInitialized)
        {
            Initialize();
        }
    }

    private void Initialize()
    {
        // Deferred code goes here
    }
}

Taking this approach will introduce a temporal coupling into your class - it will be dependent on some outsider calling methods in just the right order before it works properly.

Temporal Coupling is a major code smell - it makes reuse and understanding of the class much more difficult. (And keep in mind that one developer who will need to read and understand the code from scratch is yourself in six months.)

Instead, your class should take responsibility for it's own initialization - it shouldn't rely on an outside party.

One way to do this, if certain steps need to be deferred from the constructor, is to move those steps into a private method and then add a guard step to each appropriate public method ensuring the initialization is complete.

public class Example 
{
    public Example()
    {
        // Constructor
    }

    public void Open()
    {
        EnsureInitialized();
        ...
    }

    private void EnsureInitialized()
    {
        if (!mInitialized)
        {
            Initialize();
        }
    }

    private void Initialize()
    {
        // Deferred code goes here
    }
}
你如我软肋 2024-12-14 05:25:20

根据您的评论,具体问题是您只想在通过 MEF 组合创建类型时执行某些代码。在其他情况下,您希望避免代码执行。

我不确定是否有您可以参与的特定 MEF 活动。但是,您可以使用以下模式来解决该问题,

class MyPart {
  public MyPart() : this(true) {

  }
  private MyPart(bool doMefInit) {
    if (doMefInit) {
      MefInitialize();
    }
  }
  public static MyPart CreateLight() {
    return new MyPart(false);
  }
}

尽管我会质疑该模式的有效性。如果您的类型具有仅在特定托管场景中有效的代码,那么该代码可能应该被分解为 2 个独立的对象。

Based on your comments the specific problem is there is code you want to execute only when the type is created via MEF composition. In other scenarios you'd like to avoid the code execution.

I'm not sure if there is a particular MEF event you could hook into. However you could use the following pattern to work around the problem

class MyPart {
  public MyPart() : this(true) {

  }
  private MyPart(bool doMefInit) {
    if (doMefInit) {
      MefInitialize();
    }
  }
  public static MyPart CreateLight() {
    return new MyPart(false);
  }
}

Although i would question the validity of this pattern. If your type has code which is only valid in a specific hosting scenario it screams that the code should likely be factored out into 2 independent objects.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文