我们在大型WPF应用程序中使用MEF进行依赖注入。在MEF容器中,我们注册了一个共享实例( MyPriceProvider ),它提供了一些在某些计算中使用的数据。
我想并行化这些计算,但每次计算都会改变 MyPriceProvider 中的数据。因此,运行计算的每个线程都必须拥有自己的 MyPriceProvider 实例。
我为每个线程创建一个子容器,并在每个子容器中用新实例覆盖 MyPriceProvider 。
但是,当我从子容器中解析 MyCalculator 时,会创建一个对根容器中 MyPriceProvider 的共享实例的引用。
鉴于这两个类 MyCalculator 和 MyPriceProvider :
[Export]
[PartCreationPolicy(CreationPolicy.NonShared)]
public class MyCalculator
{
private readonly MyPriceProvider _priceProvider;
public MyPriceProvider PriceProvider => _priceProvider;
[ImportingConstructor]
public MyCalculator(MyPriceProvider priceProvider)
{
_priceProvider = priceProvider;
}
}
[Export]
[PartCreationPolicy(CreationPolicy.Shared)]
public class MyPriceProvider
{
}
这是一个简单的程序来重现这个问题:
public static void Main(string[] args)
{
// Create root container:
var aggregateCatalog = new AggregateCatalog();
var composablePartCatalog = new DirectoryCatalog(".", "*.exe");
aggregateCatalog.Catalogs.Add(composablePartCatalog);
var catalogProvider = new CatalogExportProvider(aggregateCatalog);
var rootContainer = new CompositionContainer(catalogProvider);
catalogProvider.SourceProvider = rootContainer;
// Resolve shared MyPriceProvider from root:
var priceProviderFromRoot = rootContainer.GetExportedValue<MyPriceProvider>();
// Create child container with single ExportProvider (rootContainer)
var childContainer = new CompositionContainer(rootContainer);
// Overwrite MyPriceProvider in child container
var myPriceProvider = new MyPriceProvider();
childContainer.ComposeExportedValue(myPriceProvider);
// Resolve MyCalculator from child Container
var calculatorFromChildProvider = childContainer.GetExportedValue<MyCalculator>();
if (calculatorFromChildProvider.PriceProvider == priceProviderFromRoot)
{
// PriceProvider resolved from MyCalculator is shared instance from root container, NOT the overwritten instance.
}
}
我相信我明白为什么 MyCalculator 会获取对 MyPriceProvider 的共享实例的引用,因为 MyCalculator 已在根容器中注册,以及何时MEF正在解析它的依赖关系,它不知道在子容器中覆盖了 MyPriceProvider 。
我无法以任何方式更改根容器,因为我将创建多个子容器以供并行使用,并且所有容器都将共享相同的根容器。
我有什么方法可以配置子容器,以便 MyCalculator 在从子容器中解析时获取被覆盖的实例?