MEF - 我可以创建实例并让它们在 MEF 内自动组合吗?

发布于 2024-10-07 13:01:20 字数 1380 浏览 0 评论 0原文

据我了解,为了使导入/导出属性能够正确地相互连接,我必须对每个具有这些属性的新实例调用 compositionContainerInstance.Compose(...)

是否有可能自动发生这种情况,这样每当我创建某个可组合类的新实例时就不必这样做?

这将是一个例子,虽然很长,但它抽象了我遇到的问题。

public class Worker1
{
    [Import(typeof(IDataProvider))]
    public IDataProvider DataProvider;

    public Worker2 second;
    //use data provider to perform logic
}

public class Worker2
{
    [Import(typeof(IDataProvider))]
    public IDataProvider DataProvider;

    //use data provider to perform logic
}

[Export(typeof(IDataProvider))]
public class GeoDataProvider : IDataProvider
{
    //implements logic
}

public class Container
{
    private Worker1 t1;
    public void Init()
    {
        AggregateCatalog cat = new AggregateCatalog();
        cat.Catalogs.Add(new AssemblyCatalog(Assembly.GetExecutingAssembly()));
        cat.Catalogs.Add(new DirectoryCatalog("."));

        CompositionContainer c = new CompositionContainer(cat);
        c.ComposeParts(new GeoDataProvider(), this);
    }

    public void PerformLogic()
    {
        t1 = new Worker1;
        //here it fails because I need c.ComposeParts(t1):
        t1.DoSomethingWithProvider();
        //but even if I do c.ComposeParts(t1), still the t1.second.DataProvider will be null
        //how to avoid this?
    }
}

我希望有一种方法可以自由创建 Worker1/Worker2 的新实例,而无需知道它们必须在使用前组合。这可行吗?

As I understand, in order for Import/Export attributes to be correctly connected to each other, I have to call compositionContainerInstance.Compose(...) with each new instance that has these attributes.

Is it possible to have this happening automatically, so I don't have to do it whenever I create a new instance of some composable class?

This would be an example, although lengthly, it abstracts the problem I have.

public class Worker1
{
    [Import(typeof(IDataProvider))]
    public IDataProvider DataProvider;

    public Worker2 second;
    //use data provider to perform logic
}

public class Worker2
{
    [Import(typeof(IDataProvider))]
    public IDataProvider DataProvider;

    //use data provider to perform logic
}

[Export(typeof(IDataProvider))]
public class GeoDataProvider : IDataProvider
{
    //implements logic
}

public class Container
{
    private Worker1 t1;
    public void Init()
    {
        AggregateCatalog cat = new AggregateCatalog();
        cat.Catalogs.Add(new AssemblyCatalog(Assembly.GetExecutingAssembly()));
        cat.Catalogs.Add(new DirectoryCatalog("."));

        CompositionContainer c = new CompositionContainer(cat);
        c.ComposeParts(new GeoDataProvider(), this);
    }

    public void PerformLogic()
    {
        t1 = new Worker1;
        //here it fails because I need c.ComposeParts(t1):
        t1.DoSomethingWithProvider();
        //but even if I do c.ComposeParts(t1), still the t1.second.DataProvider will be null
        //how to avoid this?
    }
}

What I'm hoping for is a way to freely create new instances of Worker1/Worker2 without needing to know that they have to be composed before usage. Is that feasible?

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

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

发布评论

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

评论(1

丘比特射中我 2024-10-14 13:01:20

有人必须知道他们需要保持冷静。

如果您要自由创建 Worker1 和 Work2 实例而不是让 MEF 创建它们,那么您还必须给 MEF 一个机会来满足新实例的导入,否则正如您所发现的,IDataProvider 字段永远不会被填写。

下面是一个示例,您只需让 MEF 根据需要创建类。只需调用一次“ComposeParts”即可完成所有设置。

[Export]
public class Worker1
{
  [Import]
  public IDataProvider DataProvider;

  [Import]
  public Worker2 second;

  //use data provider to perform logic
  public void DoSomethingWithProvider() {
    }
}

[Export]
public class Worker2
{
  [Import]
  public IDataProvider DataProvider;

  //use data provider to perform logic
}

[Export( typeof( IDataProvider ) )]
public class GeoDataProvider : IDataProvider
{
  //implements logic
}

public class Container
{
  [Import]
  private Worker1 t1;

  public void Init()
  {
    AggregateCatalog cat = new AggregateCatalog();
    cat.Catalogs.Add( new AssemblyCatalog( Assembly.GetExecutingAssembly() ) );
    cat.Catalogs.Add( new DirectoryCatalog( "." ) );

    CompositionContainer c = new CompositionContainer( cat );
    c.ComposeParts( this );
  }

  public void PerformLogic()
  {
    t1.DoSomethingWithProvider();
  }
}

Someone has to know that they need composed.

If you're going to freely create Worker1 and Work2 instances rather than letting MEF create them then you have to also give MEF a chance to satisfy the imports of new instances or as you've discovered, the IDataProvider field is never filled out.

Here's an example where you just let MEF create the classes as needed. Only one 'ComposeParts' call is needed to get everything setup.

[Export]
public class Worker1
{
  [Import]
  public IDataProvider DataProvider;

  [Import]
  public Worker2 second;

  //use data provider to perform logic
  public void DoSomethingWithProvider() {
    }
}

[Export]
public class Worker2
{
  [Import]
  public IDataProvider DataProvider;

  //use data provider to perform logic
}

[Export( typeof( IDataProvider ) )]
public class GeoDataProvider : IDataProvider
{
  //implements logic
}

public class Container
{
  [Import]
  private Worker1 t1;

  public void Init()
  {
    AggregateCatalog cat = new AggregateCatalog();
    cat.Catalogs.Add( new AssemblyCatalog( Assembly.GetExecutingAssembly() ) );
    cat.Catalogs.Add( new DirectoryCatalog( "." ) );

    CompositionContainer c = new CompositionContainer( cat );
    c.ComposeParts( this );
  }

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