这就是我希望它如何工作的方式
container.GetButDoNotCreate<T>(); // should throw (or can return null) if container doesn't contain an instance matching the contract
var x = container.GetExportedValue<T>();
var y = container.GetButDoNotCreate<T>(); // should return the object created in previous step
Assert.That(x).IsSameAs(y);
Run Code Online (Sandbox Code Playgroud)
不同之处在于,如果容器不包含实例,则此方法不会创建实例.它是一个纯粹的get,如果它存在于容器中,请将此对象告诉我.我需要它用于我的测试,我不希望测试代码在生产容器中创建对象(如果它们没有创建)只使用现有的对象.只有生产代码才能向容器添加/删除对象.
发布到 MEF codeplex论坛但没有回复.所以希望SO上的某个人可能有答案.此外,如果我需要将该函数编写为扩展方法......那也可以作为答案.
这是我的解决方案。起初我尝试创建一个扩展方法。我尝试了几件事,阅读文档并探索了容器和目录上的可用属性、事件和方法,但我无法使任何工作发挥作用。
经过思考这个问题,我能想到的唯一解决办法就是创建一个基于 CompositionContainer 并实现 GetButDoNotCreate 方法的派生容器。
更新:我在发布后意识到该解决方案仅适用于您发布的简单示例,其中仅使用 GetExportedValue 来检索零件简单零件。除非您将容器用作没有 [Import] 的部件的简单服务定位器,否则在创建具有 [Import] 的部件时将不起作用。
这是实现:
using System;
using System.Collections.Generic;
using System.ComponentModel.Composition.Hosting;
using System.ComponentModel.Composition.Primitives;
namespace GetButNotCreate
{
public class CustomContainer : CompositionContainer
{
private List<Type> composedTypes = new List<Type>();
public CustomContainer(ComposablePartCatalog catalog)
: base(catalog)
{
}
public new T GetExportedValue<T>()
{
if (!composedTypes.Contains(typeof(T)))
composedTypes.Add(typeof(T));
return base.GetExportedValue<T>();
}
public T GetButDoNotCreate<T>()
{
if (composedTypes.Contains(typeof(T)))
{
return base.GetExportedValue<T>();
}
throw new Exception("Type has not been composed yet.");
}
}
}
Run Code Online (Sandbox Code Playgroud)
它的工作原理是重写 GetExportedValue 方法来跟踪迄今为止已组合的类型,然后使用它来检查 GetButNotCreate 中的类型组合。我抛出了一个异常,就像你在问题中提到的那样。
当然,您可能需要重写 GetExportedValue 的重载(除非您不使用它们,但即便如此,为了安全起见我还是会重写它们),并且如果您使用该类,可能还需要添加其他构造函数和其他内容。在这个例子中,我做了最少的工作来让它工作。
以下是测试新方法的单元测试:
using System.ComponentModel.Composition;
using System.ComponentModel.Composition.Hosting;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System;
namespace GetButNotCreate
{
public interface IInterface { }
[Export(typeof(IInterface))]
public class MyClass : IInterface
{
}
[TestClass]
public class UnitTest1
{
[TestMethod]
[ExpectedException(typeof(Exception), "Type has not been composed yet.")]
public void GetButNotCreate_will_throw_exception_if_type_not_composed_yet()
{
var catalog = new AssemblyCatalog(typeof(UnitTest1).Assembly);
CustomContainer container = new CustomContainer(catalog);
container.ComposeParts(this);
var test = container.GetButDoNotCreate<IInterface>();
}
[TestMethod]
public void GetButNotCreate_will_return_type_if_it_as_been_composed()
{
var catalog = new AssemblyCatalog(typeof(UnitTest1).Assembly);
CustomContainer container = new CustomContainer(catalog);
container.ComposeParts(this);
var x = container.GetExportedValue<IInterface>();
var y = container.GetButDoNotCreate<IInterface>();
Assert.IsNotNull(y);
Assert.AreEqual(x, y);
}
}
}
Run Code Online (Sandbox Code Playgroud)
它表明,如果从未导出该类型,则 GetButNotCreate 将引发异常;如果已导入该类型,则 GetButNotCreate 将返回该类型。
我无法在任何地方找到任何钩子来检查(不诉诸反射)以查看 MEF 是否已组成一部分,因此这个 CustomContainer 解决方案将是我最好的选择。
| 归档时间: |
|
| 查看次数: |
1767 次 |
| 最近记录: |