Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/279.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# MEF出口工厂<;T>;-如何在长时间运行的应用程序中正确处理?_C#_Memory Management_Mef_Factory_Object Lifetime - Fatal编程技术网

C# MEF出口工厂<;T>;-如何在长时间运行的应用程序中正确处理?

C# MEF出口工厂<;T>;-如何在长时间运行的应用程序中正确处理?,c#,memory-management,mef,factory,object-lifetime,C#,Memory Management,Mef,Factory,Object Lifetime,基本上,是否有一种简单的方法来处理由导出工厂创建的导入?我问这个问题的原因是,导出通常包含对仍然存在的东西的引用,例如EventAggregator。我不想遇到这样一个问题,我正在创建数百个这样的程序,并在不必要的时候将它们放在一边 我注意到,当我创建对象时,我得到了一个带有Dispose的ExportLifetimeContext。但是,我不想将请求ViewModel副本的ExportLifetimeContext传回给我的ViewModels,因此我会传回该值。(return Factory

基本上,是否有一种简单的方法来处理由
导出工厂创建的导入?我问这个问题的原因是,导出通常包含对仍然存在的东西的引用,例如EventAggregator。我不想遇到这样一个问题,我正在创建数百个这样的程序,并在不必要的时候将它们放在一边


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

当您在
ExportLifetimeContext
上调用
Dispose
时,它将在创建
T
过程中涉及的任何
非共享
部分上调用Dispose。它不会处理任何
共享的
组件。这是一种安全行为,因为如果实例化
非共享的
部分纯粹是为了满足
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
实例是
共享的
还是
非共享的
,因此您有处置共享组件的风险

我认为挂起ExportedLifetimeContext的实例是实现所需的唯一安全方法

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

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.
  }
}
公共类导出包装器:IDisposable
{
私有只读ExportLifetimeContext上下文;
公共ExportWrapper(ExportLifetimeContext上下文)
{
this.context=上下文;
}
公共价值
{
获取{return context.Value;}
}
公共空间处置()
{
context.Dispose();
}
公共静态隐式运算符T(ExportWrapper)
{
返回wrapper.Value;
}
公共静态隐式运算符ExportWrapper(ExportLifetimeContext上下文)
{
返回新的ExportWrapper(上下文);
}
}
你可能会:

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.
  }
}
[导入(类型化(IBar))]
公共ExportFactory BarFactory{get;set;}
公共无效DoSomethingWithBar()
{
使用(ExportWrapper=BarFactory.CreateExport())
{
IBar值=包装器;
//用IBar做点什么;
//此调用完成后,将处理IBar和非共享导入。
}
}

感觉有点脏…

当您在
ExportLifetimeContext
上调用
Dispose
时,它将在创建
T
过程中涉及的任何
非共享
部分上调用Dispose。它不会处理任何
共享的
组件。这是一种安全行为,因为如果实例化
非共享的
部分纯粹是为了满足
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
实例是
共享的
还是
非共享的
,因此您有处置共享组件的风险

我认为挂起ExportedLifetimeContext的实例是实现所需的唯一安全方法

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

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.
  }
}
公共类导出包装器:IDisposable
{
私有只读ExportLifetimeContext上下文;
公共ExportWrapper(ExportLifetimeContext上下文)
{
this.context=上下文;
}
公共价值
{
获取{return context.Value;}
}
公共空间处置()
{
context.Dispose();
}
公共静态隐式运算符T(ExportWrapper)
{
返回wrapper.Value;
}
公共静态隐式运算符ExportWrapper(ExportLifetimeContext上下文)
{
返回新的ExportWrapper(上下文);
}
}
你可能会:

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.
  }
}
[导入(类型化(IBar))]
公共ExportFactory BarFactory{get;set;}
公共无效DoSomethingWithBar()
{
使用(ExportWrapper=BarFactory.CreateExport())
{
IBar值=包装器;
//用IBar做点什么;
//此调用完成后,将处理IBar和非共享导入。
}
}

感觉有点脏…

你抢先回答了我自己的问题。实际上,我创建了一个抽象的ExportFactoryController和一个IEExportFactoryController,它保存了创建的部件和ExportLifeTime上下文的字典。然后,我公开Dispose(T部分),它从字典中查找上下文并将其处理/从字典中删除。我还有一个DisposeAll(),它处理字典中存储的所有上下文并清除字典缓存。唯一让人讨厌的是我的
进口很多
都是平淡无奇的:
[ImportMany]无数的工厂进口很多
都是平淡无奇的:
[ImportMany]无数的工厂