2

基本上,有没有一种简单的方法来处理由ExportFactory<T>? 我问的原因是因为导出通常包含对仍然存在的东西的引用,例如 EventAggregator。我不想遇到这样的问题:我创建了数百个这样的东西,并在不需要时让它们闲置。

我注意到,当我创建对象时,我会返回一个ExportLifetimeContext<T>带有 Dispose 的对象。但是,我不想ExportLifetimeContext向我的 ViewModel 传回请求 ViewModel 的副本,因此我将值传回。( return Factory.Single(v => v.Metadata.Name.Equals(name)).CreateExport().Value;)

4

1 回答 1

0

当您调用DisposeanExportLifetimeContext<T>时,它将调用 dispose 在NonShared创建T. 它不会丢弃任何Shared组件。这是一种安全的行为,因为如果这些NonShared部件被实例化纯粹是为了满足 for 的导入T,那么它们可以安全地被处置,因为它们不会被任何其他导入使用。

我认为您可以实现它的唯一其他方法是自定义Dispose方法以将 dispose 调用链接到您导入的任何其他成员属性,例如:

[Export(typeof(IFoo))]
public class Foo : IFoo, IDisposable
{
    [Import]
    public IBar Bar { get; set; }

    public void Dispose()
    {
        var barDisposable = Bar as IDisposable;
        if (barDisposable != null) 
            barDisposable.Dispose();
    }
}

但是由于您的类型不知道导入的实例是否IBar是,Shared或者NonShared您冒着处置共享组件的风险。

我认为挂在实例上ExportedLifetimeContext<T>是实现你想要的唯一安全的方法。

不确定这是否有帮助,感觉像是不必要的包装,但你可以:

public class ExportWrapper<T> : IDisposable
{
  private readonly ExportLifetimeContext<T> context;

  public ExportWrapper<T>(ExportLifetimeContext<T> context)
  {
    this.context = context;
  }

  public T Value 
  {
    get { return context.Value; }
  }

  public void Dispose()
  {
    context.Dispose();
  }

  public static implicit operator T(ExportWrapper<T> wrapper)
  {
    return wrapper.Value;
  }

  public static implicit operator ExportWrapper<T>(ExportLifetimeContext<T> context)
  {
    return new ExportWrapper<T>(context);
  }
}

你可能会:

[Import(typeof(IBar))]
public ExportFactory<IBar> BarFactory { get; set; }

public void DoSomethingWithBar()
{
  using (ExportWrapper<IBar> wrapper = BarFactory.CreateExport())
  {
    IBar value = wrapper;
    // Do something with IBar;
    // IBar and NonShared imports will be disposed of after this call finishes.
  }
}

感觉有点脏……

于 2011-07-01T18:46:33.730 回答