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