这就是我希望它如何工作的方式
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);
不同之处在于,如果容器不包含实例,则此方法不会创建实例.它是一个纯粹的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.");
        }
    }
}
它的工作原理是重写 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);
        }
    }
}
它表明,如果从未导出该类型,则 GetButNotCreate 将引发异常;如果已导入该类型,则 GetButNotCreate 将返回该类型。
我无法在任何地方找到任何钩子来检查(不诉诸反射)以查看 MEF 是否已组成一部分,因此这个 CustomContainer 解决方案将是我最好的选择。
| 归档时间: | 
 | 
| 查看次数: | 1767 次 | 
| 最近记录: |