I try to export the following interface:
public interface ITree<T> where T : IComparable
A class which implements the interface:
public class Tree<T> : ITree<T> where T : IComparable
In a Unit Test Class I do the following:
[TestClass]
public class TreeTest
{
[TestInitialize()]
public void InitialTest()
{
RegistrationBuilder registrationITreeBuilder = new RegistrationBuilder();
//export all classes which implement ITree
registrationITreeBuilder.ForTypesMatching(t => t.GetInterface(typeof(ITree<>).Name) != null).Export<ITree<int>>();
registrationITreeBuilder.ForType<TreeTest>().ImportProperty(p => p.TreeInstances,ib=>ib.AsMany(true)); //TreeTest - the unit test class
var catalog = new AggregateCatalog(
new AssemblyCatalog(Assembly.GetExecutingAssembly(), registrationTreeTestBuilder), //unit test project
new AssemblyCatalog(typeof(ITree<>).Assembly, registrationITreeBuilder)
);
//Create the current composition container to create the parts
var container = new CompositionContainer(catalog);
container.ComposeParts(this);
}
public IEnumerable<ITree<int>> TreeInstances { get; set; }
}
After the InitialTest() method is executed the property TreeInstances is null . When adding the container to the watch, I see under container.Catalog.Parts
{Get.the.Solution.DataStructure.Tree({0})}
with the ExportDefinition (ContractName="Get.the.Solution.DataStructure.ITree(System.Int32)")}
which should be correct. But there is no ImportDefinition although I set a ImportProperty definition.
Anyone know how to fix this?
The ComposeParts(...)
call is actually meant to be used by the attributed programming model of MEF. What you are using in your unit test is using the convention based programming model.
Personally I would not mix those two, but if you want a quick fix here, you just add the [ImportMany]
Attribute to your TreeInstances
property and your test project will work.
I would suggest using a separate type here to host the tree instances, exporting it in your builder and getting it from your container in the test with an GetExportedValue
call. This would mean your test class would look something like this:
[TestClass]
public class TreeTest
{
private CompositionContainer _Container;
private class Trees
{
public IEnumerable<ITree<int>> TreeInstances { get; set; }
}
[TestInitialize()]
public void InitialTest()
{
...
//add the Export<Trees>() in your code
registrationITreeBuilder.ForType<Trees>().ImportProperty(tt => tt.TreeInstances, ib => ib.AsMany()).Export<Trees>();
...
}
[TestMethod]
public void TestMethod1()
{
var trees = _Container.GetExportedValue<Trees>();
}
}
This way you could also add a cleanup method for your test to get rid of the CompositionContainer
in case you allocated resources you need to dispose.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.