PageRenderTime 71ms CodeModel.GetById 14ms RepoModel.GetById 0ms app.codeStats 0ms

/mcs/class/System.ComponentModel.Composition/Tests/ComponentModelUnitTest/System/ComponentModel/Composition/MetadataTests.cs

https://github.com/iainlane/mono
C# | 1215 lines | 927 code | 240 blank | 48 comment | 3 complexity | e739a6fa303b007c64a2204b8534521e MD5 | raw file
  1. // -----------------------------------------------------------------------
  2. // Copyright (c) Microsoft Corporation. All rights reserved.
  3. // -----------------------------------------------------------------------
  4. using System;
  5. using System.Collections.Generic;
  6. using System.ComponentModel.Composition;
  7. using System.ComponentModel.Composition.Factories;
  8. using System.ComponentModel.Composition.Hosting;
  9. using System.ComponentModel.Composition.Primitives;
  10. using System.ComponentModel.Composition.UnitTesting;
  11. using System.Linq;
  12. using Microsoft.VisualStudio.TestTools.UnitTesting;
  13. using System.UnitTesting;
  14. using System.Reflection;
  15. using System.Collections.ObjectModel;
  16. namespace System.ComponentModel.Composition
  17. {
  18. [TestClass]
  19. public class MetadataTests
  20. {
  21. #region Tests for metadata on exports
  22. public enum SimpleEnum
  23. {
  24. First
  25. }
  26. [PartNotDiscoverable]
  27. [Export]
  28. [ExportMetadata("String", "42")]
  29. [ExportMetadata("Int", 42)]
  30. [ExportMetadata("Float", 42.0f)]
  31. [ExportMetadata("Enum", SimpleEnum.First)]
  32. [ExportMetadata("Type", typeof(string))]
  33. [ExportMetadata("Object", 42)]
  34. public class SimpleMetadataExporter
  35. {
  36. }
  37. [PartNotDiscoverable]
  38. [Export]
  39. [ExportMetadata("String", null)] // null
  40. [ExportMetadata("Int", 42)]
  41. [ExportMetadata("Float", 42.0f)]
  42. [ExportMetadata("Enum", SimpleEnum.First)]
  43. [ExportMetadata("Type", typeof(string))]
  44. [ExportMetadata("Object", 42)]
  45. public class SimpleMetadataExporterWithNullReferenceValue
  46. {
  47. }
  48. [PartNotDiscoverable]
  49. [Export]
  50. [ExportMetadata("String", "42")]
  51. [ExportMetadata("Int", null)] //null
  52. [ExportMetadata("Float", 42.0f)]
  53. [ExportMetadata("Enum", SimpleEnum.First)]
  54. [ExportMetadata("Type", typeof(string))]
  55. [ExportMetadata("Object", 42)]
  56. public class SimpleMetadataExporterWithNullNonReferenceValue
  57. {
  58. }
  59. [PartNotDiscoverable]
  60. [Export]
  61. [ExportMetadata("String", "42")]
  62. [ExportMetadata("Int", "42")] // wrong type
  63. [ExportMetadata("Float", 42.0f)]
  64. [ExportMetadata("Enum", SimpleEnum.First)]
  65. [ExportMetadata("Type", typeof(string))]
  66. [ExportMetadata("Object", 42)]
  67. public class SimpleMetadataExporterWithTypeMismatch
  68. {
  69. }
  70. public interface ISimpleMetadataView
  71. {
  72. string String { get; }
  73. int Int { get; }
  74. float Float { get; }
  75. SimpleEnum Enum { get; }
  76. Type Type { get; }
  77. object Object { get; }
  78. }
  79. [TestMethod]
  80. public void SimpleMetadataTest()
  81. {
  82. var container = ContainerFactory.Create();
  83. container.ComposeParts(new SimpleMetadataExporter());
  84. var export = container.GetExport<SimpleMetadataExporter, ISimpleMetadataView>();
  85. Assert.AreEqual("42", export.Metadata.String);
  86. Assert.AreEqual(42, export.Metadata.Int);
  87. Assert.AreEqual(42.0f, export.Metadata.Float);
  88. Assert.AreEqual(SimpleEnum.First, export.Metadata.Enum);
  89. Assert.AreEqual(typeof(string), export.Metadata.Type);
  90. Assert.AreEqual(42, export.Metadata.Object);
  91. }
  92. [TestMethod]
  93. public void SimpleMetadataTestWithNullReferenceValue()
  94. {
  95. var container = ContainerFactory.Create();
  96. container.ComposeParts(new SimpleMetadataExporterWithNullReferenceValue());
  97. var export = container.GetExport<SimpleMetadataExporterWithNullReferenceValue, ISimpleMetadataView>();
  98. Assert.AreEqual(null, export.Metadata.String);
  99. Assert.AreEqual(42, export.Metadata.Int);
  100. Assert.AreEqual(42.0f, export.Metadata.Float);
  101. Assert.AreEqual(SimpleEnum.First, export.Metadata.Enum);
  102. Assert.AreEqual(typeof(string), export.Metadata.Type);
  103. Assert.AreEqual(42, export.Metadata.Object);
  104. }
  105. [TestMethod]
  106. public void SimpleMetadataTestWithNullNonReferenceValue()
  107. {
  108. var container = ContainerFactory.Create();
  109. container.ComposeParts(new SimpleMetadataExporterWithNullNonReferenceValue());
  110. var exports = container.GetExports<SimpleMetadataExporterWithNullNonReferenceValue, ISimpleMetadataView>();
  111. Assert.IsFalse(exports.Any());
  112. }
  113. [TestMethod]
  114. public void SimpleMetadataTestWithTypeMismatch()
  115. {
  116. var container = ContainerFactory.Create();
  117. container.ComposeParts(new SimpleMetadataExporterWithTypeMismatch());
  118. var exports = container.GetExports<SimpleMetadataExporterWithTypeMismatch, ISimpleMetadataView>();
  119. Assert.IsFalse(exports.Any());
  120. }
  121. [TestMethod]
  122. public void ValidMetadataTest()
  123. {
  124. var container = ContainerFactory.Create();
  125. CompositionBatch batch = new CompositionBatch();
  126. batch.AddPart(new MyExporterWithValidMetadata());
  127. container.Compose(batch);
  128. var typeVi = container.GetExport<MyExporterWithValidMetadata, IDictionary<string, object>>();
  129. var metadataFoo = typeVi.Metadata["foo"] as IList<string>;
  130. Assert.AreEqual(2, metadataFoo.Count(), "There are should be two items in the metadata foo's collection");
  131. Assert.IsTrue(metadataFoo.Contains("bar1"), "The metadata collection should include value 'bar1'");
  132. Assert.IsTrue(metadataFoo.Contains("bar2"), "The metadata collection should include value 'bar2'");
  133. Assert.AreEqual("world", typeVi.Metadata["hello"], "The single item metadata should be present");
  134. Assert.AreEqual("GoodOneValue2", typeVi.Metadata["GoodOne2"], "The metadata supplied by strong attribute should also be present");
  135. var metadataAcme = typeVi.Metadata["acme"] as IList<object>;
  136. Assert.AreEqual(2, metadataAcme.Count(), "There are should be two items in the metadata acme's collection");
  137. Assert.IsTrue(metadataAcme.Contains("acmebar"), "The metadata collection should include value 'bar'");
  138. Assert.IsTrue(metadataAcme.Contains(2.0), "The metadata collection should include value 2");
  139. var memberVi = container.GetExport<Func<double>, IDictionary<string, object>>("ContractForValidMetadata");
  140. var metadataBar = memberVi.Metadata["bar"] as IList<string>;
  141. Assert.AreEqual(2, metadataBar.Count(), "There are should be two items in the metadata bar's collection");
  142. Assert.IsTrue(metadataBar.Contains("foo1"), "The metadata collection should include value 'foo1'");
  143. Assert.IsTrue(metadataBar.Contains("foo2"), "The metadata collection should include value 'foo2'");
  144. Assert.AreEqual("hello", memberVi.Metadata["world"], "The single item metadata should be present");
  145. Assert.AreEqual("GoodOneValue2", memberVi.Metadata["GoodOne2"], "The metadata supplied by strong attribute should also be present");
  146. var metadataStuff = memberVi.Metadata["stuff"] as IList<object>;
  147. Assert.AreEqual(2, metadataAcme.Count(), "There are should be two items in the metadata acme's collection");
  148. Assert.IsTrue(metadataStuff.Contains("acmebar"), "The metadata collection should include value 'acmebar'");
  149. Assert.IsTrue(metadataStuff.Contains(2.0), "The metadata collection should include value 2");
  150. }
  151. [TestMethod]
  152. public void ValidMetadataDiscoveredByComponentCatalogTest()
  153. {
  154. var container = ContainerFactory.CreateWithDefaultAttributedCatalog();
  155. ValidMetadataDiscoveredByCatalog(container);
  156. }
  157. private void ValidMetadataDiscoveredByCatalog(CompositionContainer container)
  158. {
  159. var export1 = container.GetExport<MyExporterWithValidMetadata, IDictionary<string, object>>();
  160. var metadataFoo = export1.Metadata["foo"] as IList<string>;
  161. Assert.AreEqual(2, metadataFoo.Count(), "There are should be two items in the metadata foo's collection");
  162. Assert.IsTrue(metadataFoo.Contains("bar1"), "The metadata collection should include value 'bar1'");
  163. Assert.IsTrue(metadataFoo.Contains("bar2"), "The metadata collection should include value 'bar2'");
  164. Assert.AreEqual("world", export1.Metadata["hello"], "The single item metadata should also be present");
  165. Assert.AreEqual("GoodOneValue2", export1.Metadata["GoodOne2"], "The metadata supplied by strong attribute should also be present");
  166. var metadataAcme = export1.Metadata["acme"] as IList<object>;
  167. Assert.AreEqual(2, metadataAcme.Count(), "There are should be two items in the metadata acme's collection");
  168. Assert.IsTrue(metadataAcme.Contains("acmebar"), "The metadata collection should include value 'bar'");
  169. Assert.IsTrue(metadataAcme.Contains(2.0), "The metadata collection should include value 2");
  170. var export2 = container.GetExport<Func<double>, IDictionary<string, object>>("ContractForValidMetadata");
  171. var metadataBar = export2.Metadata["bar"] as IList<string>;
  172. Assert.AreEqual(2, metadataBar.Count(), "There are should be two items in the metadata foo's collection");
  173. Assert.IsTrue(metadataBar.Contains("foo1"), "The metadata collection should include value 'foo1'");
  174. Assert.IsTrue(metadataBar.Contains("foo2"), "The metadata collection should include value 'foo2'");
  175. Assert.AreEqual("hello", export2.Metadata["world"], "The single item metadata should also be present");
  176. Assert.AreEqual("GoodOneValue2", export2.Metadata["GoodOne2"], "The metadata supplied by strong attribute should also be present");
  177. var metadataStuff = export2.Metadata["stuff"] as IList<object>;
  178. Assert.AreEqual(2, metadataAcme.Count(), "There are should be two items in the metadata acme's collection");
  179. Assert.IsTrue(metadataStuff.Contains("acmebar"), "The metadata collection should include value 'acmebar'");
  180. Assert.IsTrue(metadataStuff.Contains(2.0), "The metadata collection should include value 2");
  181. }
  182. [AttributeUsage(AttributeTargets.All, AllowMultiple = true)]
  183. [MetadataAttribute]
  184. public class BadStrongMetadata : Attribute
  185. {
  186. public string SelfConflicted { get { return "SelfConflictedValue"; } }
  187. }
  188. [Export]
  189. [BadStrongMetadata]
  190. [ExportMetadata("InvalidCollection", "InvalidCollectionValue1")]
  191. [ExportMetadata("InvalidCollection", "InvalidCollectionValue2", IsMultiple = true)]
  192. [BadStrongMetadata]
  193. [ExportMetadata("RepeatedMetadata", "RepeatedMetadataValue1")]
  194. [ExportMetadata("RepeatedMetadata", "RepeatedMetadataValue2")]
  195. [ExportMetadata("GoodOne1", "GoodOneValue1")]
  196. [ExportMetadata("ConflictedOne1", "ConfilictedOneValue1")]
  197. [GoodStrongMetadata]
  198. [ExportMetadata("ConflictedOne2", "ConflictedOne2Value2")]
  199. [PartNotDiscoverable]
  200. public class MyExporterWithInvalidMetadata
  201. {
  202. [Export("ContractForInvalidMetadata")]
  203. [ExportMetadata("ConflictedOne1", "ConfilictedOneValue1")]
  204. [GoodStrongMetadata]
  205. [ExportMetadata("ConflictedOne2", "ConflictedOne2Value2")]
  206. [ExportMetadata("RepeatedMetadata", "RepeatedMetadataValue1")]
  207. [ExportMetadata("RepeatedMetadata", "RepeatedMetadataValue2")]
  208. [BadStrongMetadata]
  209. [ExportMetadata("InvalidCollection", "InvalidCollectionValue1")]
  210. [ExportMetadata("InvalidCollection", "InvalidCollectionValue2", IsMultiple = true)]
  211. [BadStrongMetadata]
  212. [ExportMetadata("GoodOne1", "GoodOneValue1")]
  213. public double DoSomething() { return 0.618; }
  214. }
  215. [Export]
  216. [ExportMetadata("DuplicateMetadataName", "My Name")]
  217. [ExportMetadata("DuplicateMetadataName", "Your Name")]
  218. [PartNotDiscoverable]
  219. public class ClassWithInvalidDuplicateMetadataOnType
  220. {
  221. }
  222. [TestMethod]
  223. public void InvalidDuplicateMetadataOnType_ShouldThrow()
  224. {
  225. var part = AttributedModelServices.CreatePart(new ClassWithInvalidDuplicateMetadataOnType());
  226. var export = part.ExportDefinitions.First();
  227. var ex = ExceptionAssert.Throws<InvalidOperationException>(RetryMode.DoNotRetry, () =>
  228. {
  229. var metadata = export.Metadata;
  230. });
  231. Assert.IsTrue(ex.Message.Contains("DuplicateMetadataName"));
  232. }
  233. [PartNotDiscoverable]
  234. public class ClassWithInvalidDuplicateMetadataOnMember
  235. {
  236. [Export]
  237. [ExportMetadata("DuplicateMetadataName", "My Name")]
  238. [ExportMetadata("DuplicateMetadataName", "Your Name")]
  239. public ClassWithDuplicateMetadataOnMember Member { get; set; }
  240. }
  241. [TestMethod]
  242. public void InvalidDuplicateMetadataOnMember_ShouldThrow()
  243. {
  244. var part = AttributedModelServices.CreatePart(new ClassWithInvalidDuplicateMetadataOnMember());
  245. var export = part.ExportDefinitions.First();
  246. var ex = ExceptionAssert.Throws<InvalidOperationException>(RetryMode.DoNotRetry, () =>
  247. {
  248. var metadata = export.Metadata;
  249. });
  250. Assert.IsTrue(ex.Message.Contains("DuplicateMetadataName"));
  251. }
  252. [Export]
  253. [ExportMetadata("DuplicateMetadataName", "My Name", IsMultiple=true)]
  254. [ExportMetadata("DuplicateMetadataName", "Your Name", IsMultiple=true)]
  255. public class ClassWithValidDuplicateMetadataOnType
  256. {
  257. }
  258. [TestMethod]
  259. public void ValidDuplicateMetadataOnType_ShouldDiscoverAllMetadata()
  260. {
  261. var container = ContainerFactory.Create();
  262. CompositionBatch batch = new CompositionBatch();
  263. batch.AddPart(new ClassWithValidDuplicateMetadataOnType());
  264. container.Compose(batch);
  265. var export = container.GetExport<ClassWithValidDuplicateMetadataOnType, IDictionary<string, object>>();
  266. var names = export.Metadata["DuplicateMetadataName"] as string[];
  267. Assert.AreEqual(2, names.Length);
  268. }
  269. public class ClassWithDuplicateMetadataOnMember
  270. {
  271. [Export]
  272. [ExportMetadata("DuplicateMetadataName", "My Name", IsMultiple=true)]
  273. [ExportMetadata("DuplicateMetadataName", "Your Name", IsMultiple=true)]
  274. public ClassWithDuplicateMetadataOnMember Member { get; set; }
  275. }
  276. [TestMethod]
  277. public void ValidDuplicateMetadataOnMember_ShouldDiscoverAllMetadata()
  278. {
  279. var container = ContainerFactory.Create();
  280. CompositionBatch batch = new CompositionBatch();
  281. batch.AddPart(new ClassWithDuplicateMetadataOnMember());
  282. container.Compose(batch);
  283. var export = container.GetExport<ClassWithDuplicateMetadataOnMember, IDictionary<string, object>>();
  284. var names = export.Metadata["DuplicateMetadataName"] as string[];
  285. Assert.AreEqual(2, names.Length);
  286. }
  287. [Export]
  288. [ExportMetadata(CompositionConstants.PartCreationPolicyMetadataName, "My Policy")]
  289. [PartNotDiscoverable]
  290. public class ClassWithReservedMetadataValue
  291. {
  292. }
  293. [TestMethod]
  294. public void InvalidMetadata_UseOfReservedName_ShouldThrow()
  295. {
  296. var part = AttributedModelServices.CreatePart(new ClassWithReservedMetadataValue());
  297. var export = part.ExportDefinitions.First();
  298. var ex = ExceptionAssert.Throws<InvalidOperationException>(RetryMode.DoNotRetry, () =>
  299. {
  300. var metadata = export.Metadata;
  301. });
  302. Assert.IsTrue(ex.Message.Contains(CompositionConstants.PartCreationPolicyMetadataName));
  303. }
  304. #endregion
  305. #region Tests for weakly supported metadata as part of contract
  306. [TestMethod]
  307. [WorkItem(468388)]
  308. [Ignore]
  309. public void FailureImportForNoRequiredMetadatForExportCollection()
  310. {
  311. CompositionContainer container = ContainerFactory.Create();
  312. MyImporterWithExportCollection importer;
  313. CompositionBatch batch = new CompositionBatch();
  314. batch.AddPart(new MyExporterWithNoMetadata());
  315. batch.AddPart(importer = new MyImporterWithExportCollection());
  316. Assert.Fail();
  317. //var result = container.TryCompose();
  318. //Assert.IsTrue(result.Succeeded, "Composition should be successful because collection import is not required");
  319. //Assert.AreEqual(1, result.Issues.Count, "There should be one issue reported");
  320. //Assert.IsTrue(result.Issues[0].Description.Contains("Foo"), "The missing required metadata is 'Foo'");
  321. }
  322. [TestMethod]
  323. [WorkItem(472538)]
  324. [Ignore]
  325. public void FailureImportForNoRequiredMetadataThroughComponentCatalogTest()
  326. {
  327. var container = ContainerFactory.CreateWithDefaultAttributedCatalog();
  328. FailureImportForNoRequiredMetadataThroughCatalog(container);
  329. }
  330. private void FailureImportForNoRequiredMetadataThroughCatalog(CompositionContainer container)
  331. {
  332. Assert.Fail("This needs to be fixed, see: 472538");
  333. //var export1 = container.GetExport<MyImporterWithExport>();
  334. //export1.TryGetExportedValue().VerifyFailure(CompositionIssueId.RequiredMetadataNotFound, CompositionIssueId.CardinalityMismatch);
  335. //var export2 = container.GetExport<MyImporterWithExportCollection>();
  336. //export2.TryGetExportedValue().VerifySuccess(CompositionIssueId.RequiredMetadataNotFound);
  337. //container.TryGetExportedValue<MyImporterWithValue>().VerifyFailure(CompositionIssueId.RequiredMetadataNotFound, CompositionIssueId.CardinalityMismatch);
  338. }
  339. [TestMethod]
  340. [WorkItem(468388)]
  341. [Ignore]
  342. public void SelectiveImportBasedOnMetadataForExport()
  343. {
  344. CompositionContainer container = ContainerFactory.Create();
  345. MyImporterWithExportForSelectiveImport importer;
  346. CompositionBatch batch = new CompositionBatch();
  347. batch.AddPart(new MyExporterWithNoMetadata());
  348. batch.AddPart(new MyExporterWithMetadata());
  349. batch.AddPart(importer = new MyImporterWithExportForSelectiveImport());
  350. Assert.Fail();
  351. //var result = container.TryCompose();
  352. //Assert.IsTrue(result.Succeeded, "Composition should be successfull because one of two exports meets both the contract name and metadata requirement");
  353. //Assert.AreEqual(1, result.Issues.Count, "There should be one issue reported about the export who has no required metadata");
  354. //Assert.IsTrue(result.Issues[0].Description.Contains("Foo"), "The missing required metadata is 'Foo'");
  355. //Assert.IsNotNull(importer.ValueInfo, "The import should really get bound");
  356. }
  357. [TestMethod]
  358. [WorkItem(468388)]
  359. [Ignore]
  360. public void SelectiveImportBasedOnMetadataForExportCollection()
  361. {
  362. CompositionContainer container = ContainerFactory.Create();
  363. MyImporterWithExportCollectionForSelectiveImport importer;
  364. CompositionBatch batch = new CompositionBatch();
  365. batch.AddPart(new MyExporterWithNoMetadata());
  366. batch.AddPart(new MyExporterWithMetadata());
  367. batch.AddPart(importer = new MyImporterWithExportCollectionForSelectiveImport());
  368. Assert.Fail();
  369. //var result = container.TryCompose();
  370. //Assert.IsTrue(result.Succeeded, "Composition should be successfull in anyway for collection import");
  371. //Assert.AreEqual(1, result.Issues.Count, "There should be one issue reported however, about the export who has no required metadata");
  372. //Assert.IsTrue(result.Issues[0].Description.Contains("Foo"), "The missing required metadata is 'Foo'");
  373. //Assert.AreEqual(1, importer.ValueInfoCol.Count, "The export with required metadata should get bound");
  374. //Assert.IsNotNull(importer.ValueInfoCol[0], "The import should really get bound");
  375. }
  376. [TestMethod]
  377. [WorkItem(472538)]
  378. [Ignore]
  379. public void SelectiveImportBasedOnMetadataThruoughComponentCatalogTest()
  380. {
  381. var container = ContainerFactory.CreateWithDefaultAttributedCatalog();
  382. SelectiveImportBasedOnMetadataThruoughCatalog(container);
  383. }
  384. private void SelectiveImportBasedOnMetadataThruoughCatalog(CompositionContainer container)
  385. {
  386. Assert.Fail("This needs to be fixed, see: 472538");
  387. //var export1 = container.GetExport<MyImporterWithExportForSelectiveImport>();
  388. //export1.TryGetExportedValue().VerifySuccess(CompositionIssueId.RequiredMetadataNotFound);
  389. //var export2 = container.GetExport<MyImporterWithExportCollectionForSelectiveImport>();
  390. //export2.TryGetExportedValue().VerifySuccess(CompositionIssueId.RequiredMetadataNotFound);
  391. }
  392. [TestMethod]
  393. public void ChildParentContainerTest1()
  394. {
  395. CompositionContainer parent = ContainerFactory.Create();
  396. CompositionContainer child = new CompositionContainer(parent);
  397. CompositionBatch childBatch = new CompositionBatch();
  398. CompositionBatch parentBatch = new CompositionBatch();
  399. parentBatch.AddPart(new MyExporterWithNoMetadata());
  400. childBatch.AddPart(new MyExporterWithMetadata());
  401. parent.Compose(parentBatch);
  402. child.Compose(childBatch);
  403. var exports = child.GetExports(CreateImportDefinition(typeof(IMyExporter), "Foo"));
  404. Assert.AreEqual(1, exports.Count());
  405. }
  406. [TestMethod]
  407. public void ChildParentContainerTest2()
  408. {
  409. CompositionContainer parent = ContainerFactory.Create();
  410. CompositionContainer child = new CompositionContainer(parent);
  411. CompositionBatch childBatch = new CompositionBatch();
  412. CompositionBatch parentBatch = new CompositionBatch();
  413. parentBatch.AddPart(new MyExporterWithMetadata());
  414. childBatch.AddPart(new MyExporterWithNoMetadata());
  415. parent.Compose(parentBatch);
  416. var exports = child.GetExports(CreateImportDefinition(typeof(IMyExporter), "Foo"));
  417. Assert.AreEqual(1, exports.Count());
  418. }
  419. [TestMethod]
  420. public void ChildParentContainerTest3()
  421. {
  422. CompositionContainer parent = ContainerFactory.Create();
  423. CompositionContainer child = new CompositionContainer(parent);
  424. CompositionBatch childBatch = new CompositionBatch();
  425. CompositionBatch parentBatch = new CompositionBatch();
  426. parentBatch.AddPart(new MyExporterWithMetadata());
  427. childBatch.AddPart(new MyExporterWithMetadata());
  428. parent.Compose(parentBatch);
  429. child.Compose(childBatch);
  430. var exports = child.GetExports(CreateImportDefinition(typeof(IMyExporter), "Foo"));
  431. Assert.AreEqual(2, exports.Count(), "There should be two from child and parent container each");
  432. }
  433. private static ImportDefinition CreateImportDefinition(Type type, string metadataKey)
  434. {
  435. return new ContractBasedImportDefinition(AttributedModelServices.GetContractName(typeof(IMyExporter)), null, new KeyValuePair<string, Type>[] { new KeyValuePair<string, Type>(metadataKey, typeof(object))}, ImportCardinality.ZeroOrMore, true, true, CreationPolicy.Any);
  436. }
  437. #endregion
  438. #region Tests for strongly typed metadata as part of contract
  439. [TestMethod]
  440. [WorkItem(468388)]
  441. [Ignore]
  442. public void SelectiveImportBySTM_Export()
  443. {
  444. CompositionContainer container = ContainerFactory.Create();
  445. CompositionBatch batch = new CompositionBatch();
  446. MyImporterWithExportStronglyTypedMetadata importer;
  447. batch.AddPart(new MyExporterWithNoMetadata());
  448. batch.AddPart(new MyExporterWithMetadata());
  449. batch.AddPart(importer = new MyImporterWithExportStronglyTypedMetadata());
  450. Assert.Fail();
  451. //var result = container.TryCompose();
  452. //Assert.IsTrue(result.Succeeded, "Composition should be successful becasue one of two exports does not have required metadata");
  453. //Assert.AreEqual(1, result.Issues.Count, "There should be an issue reported about the export who has no required metadata");
  454. //Assert.IsNotNull(importer.ValueInfo, "The valid export should really get bound");
  455. //Assert.AreEqual("Bar", importer.ValueInfo.Metadata.Foo, "The value of metadata 'Foo' should be 'Bar'");
  456. }
  457. [TestMethod]
  458. [WorkItem(468388)]
  459. [Ignore]
  460. public void SelectiveImportBySTM_ExportCollection()
  461. {
  462. CompositionContainer container = ContainerFactory.Create();
  463. MyImporterWithExportCollectionStronglyTypedMetadata importer;
  464. CompositionBatch batch = new CompositionBatch();
  465. batch.AddPart(new MyExporterWithNoMetadata());
  466. batch.AddPart(new MyExporterWithMetadata());
  467. batch.AddPart(importer = new MyImporterWithExportCollectionStronglyTypedMetadata());
  468. Assert.Fail();
  469. //var result = container.TryCompose();
  470. //Assert.IsTrue(result.Succeeded, "Collection import should be successful in anyway");
  471. //Assert.AreEqual(1, result.Issues.Count, "There should be an issue reported about the export with no required metadata");
  472. //Assert.AreEqual(1, importer.ValueInfoCol.Count, "There should be only one export got bound");
  473. //Assert.AreEqual("Bar", importer.ValueInfoCol.First().Metadata.Foo, "The value of metadata 'Foo' should be 'Bar'");
  474. }
  475. [TestMethod]
  476. public void SelectiveImportBySTMThroughComponentCatalog1()
  477. {
  478. var container = ContainerFactory.CreateWithDefaultAttributedCatalog();
  479. SelectiveImportBySTMThroughCatalog1(container);
  480. }
  481. public void SelectiveImportBySTMThroughCatalog1(CompositionContainer container)
  482. {
  483. Assert.IsNotNull(container.GetExport<IMyExporter, IMetadataView>());
  484. var result2 = container.GetExports<IMyExporter, IMetadataView>();
  485. }
  486. [TestMethod]
  487. [WorkItem(468388)]
  488. [Ignore]
  489. public void SelectiveImportBySTMThroughComponentCatalog2()
  490. {
  491. var container = ContainerFactory.CreateWithDefaultAttributedCatalog();
  492. SelectiveImportBySTMThroughCatalog2(container);
  493. }
  494. public void SelectiveImportBySTMThroughCatalog2(CompositionContainer container)
  495. {
  496. Assert.Fail("This needs to be fixed, see: 472538");
  497. //var export1 = container.GetExport<MyImporterWithExportStronglyTypedMetadata>();
  498. //var result1 = export1.TryGetExportedValue().VerifySuccess(CompositionIssueId.RequiredMetadataNotFound);
  499. //Assert.IsNotNull(result1.Value.ValueInfo, "The valid export should really get bound");
  500. //Assert.AreEqual("Bar", result1.Value.ValueInfo.Metadata.Foo, "The value of metadata 'Foo' should be 'Bar'");
  501. //var export2 = container.GetExport<MyImporterWithExportCollectionStronglyTypedMetadata>();
  502. //var result2 = export2.TryGetExportedValue().VerifySuccess(CompositionIssueId.RequiredMetadataNotFound);
  503. //Assert.AreEqual(1, result2.Value.ValueInfoCol.Count, "There should be only one export got bound");
  504. //Assert.AreEqual("Bar", result2.Value.ValueInfoCol.First().Metadata.Foo, "The value of metadata 'Foo' should be 'Bar'");
  505. }
  506. [TestMethod]
  507. public void TestMultipleStronglyTypedAttributes()
  508. {
  509. var container = ContainerFactory.CreateWithDefaultAttributedCatalog();
  510. var export = container.GetExport<ExportMultiple, IMyOptions>();
  511. EnumerableAssert.AreEqual(export.Metadata.OptionNames.OrderBy(s => s), "name1", "name2", "name3");
  512. EnumerableAssert.AreEqual(export.Metadata.OptionValues.OrderBy(o => o.ToString()), "value1", "value2", "value3");
  513. }
  514. [TestMethod]
  515. public void TestMultipleStronglyTypedAttributesAsIEnumerable()
  516. {
  517. var container = ContainerFactory.CreateWithDefaultAttributedCatalog();
  518. var export = container.GetExport<ExportMultiple, IMyOptionsAsIEnumerable>();
  519. EnumerableAssert.AreEqual(export.Metadata.OptionNames.OrderBy(s => s), "name1", "name2", "name3");
  520. EnumerableAssert.AreEqual(export.Metadata.OptionValues.OrderBy(o => o.ToString()), "value1", "value2", "value3");
  521. }
  522. [TestMethod]
  523. public void TestMultipleStronglyTypedAttributesAsArray()
  524. {
  525. var container = ContainerFactory.CreateWithDefaultAttributedCatalog();
  526. var export = container.GetExport<ExportMultiple, IMyOptionsAsArray>();
  527. EnumerableAssert.AreEqual(export.Metadata.OptionNames.OrderBy(s => s), "name1", "name2", "name3");
  528. EnumerableAssert.AreEqual(export.Metadata.OptionValues.OrderBy(o => o.ToString()), "value1", "value2", "value3");
  529. }
  530. [TestMethod]
  531. public void TestMultipleStronglyTypedAttributesWithInvalidType()
  532. {
  533. var container = ContainerFactory.CreateWithDefaultAttributedCatalog();
  534. // IMyOption2 actually contains all the correct properties but just the wrong types. This should cause us to not match the exports by metadata
  535. var exports = container.GetExports<ExportMultiple, IMyOption2>();
  536. Assert.AreEqual(0, exports.Count());
  537. }
  538. [TestMethod]
  539. public void TestOptionalMetadataValueTypeMismatch()
  540. {
  541. var container = ContainerFactory.CreateWithAttributedCatalog(typeof(OptionalFooIsInt));
  542. var exports = container.GetExports<OptionalFooIsInt, IMetadataView>();
  543. Assert.AreEqual(1, exports.Count());
  544. var export = exports.Single();
  545. Assert.AreEqual(null, export.Metadata.OptionalFoo);
  546. }
  547. #endregion
  548. [ExportMetadata("Name", "FromBaseType")]
  549. public abstract class BaseClassWithMetadataButNoExport
  550. {
  551. }
  552. [Export(typeof(BaseClassWithMetadataButNoExport))]
  553. public class DerivedClassWithExportButNoMetadata : BaseClassWithMetadataButNoExport
  554. {
  555. }
  556. [TestMethod]
  557. public void Metadata_BaseClassWithMetadataButNoExport()
  558. {
  559. var container = ContainerFactory.CreateWithAttributedCatalog(
  560. typeof(BaseClassWithMetadataButNoExport),
  561. typeof(DerivedClassWithExportButNoMetadata));
  562. var export = container.GetExport<BaseClassWithMetadataButNoExport, IDictionary<string, object>>();
  563. Assert.IsFalse(export.Metadata.ContainsKey("Name"), "Export should only contain metadata from the derived!");
  564. }
  565. [InheritedExport(typeof(BaseClassWithExportButNoMetadata))]
  566. public abstract class BaseClassWithExportButNoMetadata
  567. {
  568. }
  569. [ExportMetadata("Name", "FromDerivedType")]
  570. public class DerivedClassMetadataButNoExport : BaseClassWithExportButNoMetadata
  571. {
  572. }
  573. [TestMethod]
  574. public void Metadata_BaseClassWithExportButNoMetadata()
  575. {
  576. var container = ContainerFactory.CreateWithAttributedCatalog(
  577. typeof(BaseClassWithExportButNoMetadata),
  578. typeof(DerivedClassMetadataButNoExport));
  579. var export = container.GetExport<BaseClassWithExportButNoMetadata, IDictionary<string, object>>();
  580. Assert.IsFalse(export.Metadata.ContainsKey("Name"), "Export should only contain metadata from the base!");
  581. }
  582. [Export(typeof(BaseClassWithExportAndMetadata))]
  583. [ExportMetadata("Name", "FromBaseType")]
  584. public class BaseClassWithExportAndMetadata
  585. {
  586. }
  587. [Export(typeof(DerivedClassWithExportAndMetadata))]
  588. [ExportMetadata("Name", "FromDerivedType")]
  589. public class DerivedClassWithExportAndMetadata : BaseClassWithExportAndMetadata
  590. {
  591. }
  592. [TestMethod]
  593. public void Metadata_BaseAndDerivedWithExportAndMetadata()
  594. {
  595. var container = ContainerFactory.CreateWithAttributedCatalog(
  596. typeof(BaseClassWithExportAndMetadata),
  597. typeof(DerivedClassWithExportAndMetadata));
  598. var exportBase = container.GetExport<BaseClassWithExportAndMetadata, IDictionary<string, object>>();
  599. Assert.AreEqual("FromBaseType", exportBase.Metadata["Name"]);
  600. var exportDerived = container.GetExport<DerivedClassWithExportAndMetadata, IDictionary<string, object>>();
  601. Assert.AreEqual("FromDerivedType", exportDerived.Metadata["Name"]);
  602. }
  603. [Export]
  604. [ExportMetadata("Data", null, IsMultiple=true)]
  605. [ExportMetadata("Data", false, IsMultiple=true)]
  606. [ExportMetadata("Data", Int16.MaxValue, IsMultiple = true)]
  607. [ExportMetadata("Data", Int32.MaxValue, IsMultiple = true)]
  608. [ExportMetadata("Data", Int64.MaxValue, IsMultiple = true)]
  609. [ExportMetadata("Data", UInt16.MaxValue, IsMultiple = true)]
  610. [ExportMetadata("Data", UInt32.MaxValue, IsMultiple = true)]
  611. [ExportMetadata("Data", UInt64.MaxValue, IsMultiple = true)]
  612. [ExportMetadata("Data", "String", IsMultiple = true)]
  613. [ExportMetadata("Data", typeof(ClassWithLotsOfDifferentMetadataTypes), IsMultiple = true)]
  614. [ExportMetadata("Data", CreationPolicy.NonShared, IsMultiple=true)]
  615. [ExportMetadata("Data", new object[] { 1, 2, null }, IsMultiple=true)]
  616. [CLSCompliant(false)]
  617. public class ClassWithLotsOfDifferentMetadataTypes
  618. {
  619. }
  620. [TestMethod]
  621. public void ExportWithValidCollectionOfMetadata_ShouldDiscoverAllMetadata()
  622. {
  623. var catalog = CatalogFactory.CreateAttributed(typeof(ClassWithLotsOfDifferentMetadataTypes));
  624. var export = catalog.Parts.First().ExportDefinitions.First();
  625. var data = (object[])export.Metadata["Data"];
  626. Assert.AreEqual(12, data.Length);
  627. }
  628. [Export]
  629. [ExportMetadata("Data", null, IsMultiple = true)]
  630. [ExportMetadata("Data", 1, IsMultiple = true)]
  631. [ExportMetadata("Data", 2, IsMultiple = true)]
  632. [ExportMetadata("Data", 3, IsMultiple = true)]
  633. public class ClassWithIntCollectionWithNullValue
  634. {
  635. }
  636. [TestMethod]
  637. public void ExportWithIntCollectionPlusNullValueOfMetadata_ShouldDiscoverAllMetadata()
  638. {
  639. var catalog = CatalogFactory.CreateAttributed(typeof(ClassWithIntCollectionWithNullValue));
  640. var export = catalog.Parts.First().ExportDefinitions.First();
  641. var data = (object[])export.Metadata["Data"];
  642. Assert.IsNotInstanceOfType(data, typeof(int[]));
  643. Assert.AreEqual(4, data.Length);
  644. }
  645. [AttributeUsage(AttributeTargets.Class, AllowMultiple=true)]
  646. [MetadataAttribute]
  647. public class DataAttribute : Attribute
  648. {
  649. public object Object { get; set; }
  650. }
  651. [Export]
  652. [Data(Object="42")]
  653. [Data(Object = "10")]
  654. public class ExportWithMultipleMetadata_ExportStringsAsObjects
  655. {
  656. }
  657. [Export]
  658. [Data(Object = "42")]
  659. [Data(Object = "10")]
  660. [Data(Object = null)]
  661. public class ExportWithMultipleMetadata_ExportStringsAsObjects_WithNull
  662. {
  663. }
  664. [Export]
  665. [Data(Object = 42)]
  666. [Data(Object = 10)]
  667. public class ExportWithMultipleMetadata_ExportIntsAsObjects
  668. {
  669. }
  670. [Export]
  671. [Data(Object = null)]
  672. [Data(Object = 42)]
  673. [Data(Object = 10)]
  674. public class ExportWithMultipleMetadata_ExportIntsAsObjects_WithNull
  675. {
  676. }
  677. public interface IObjectView_AsStrings
  678. {
  679. string[] Object { get; }
  680. }
  681. public interface IObjectView_AsInts
  682. {
  683. int[] Object { get; }
  684. }
  685. public interface IObjectView
  686. {
  687. object[] Object { get; }
  688. }
  689. [TestMethod]
  690. public void ExportWithMultipleMetadata_ExportStringsAsObjects_ShouldDiscoverMetadataAsStrings()
  691. {
  692. var container = ContainerFactory.Create();
  693. container.ComposeParts(new ExportWithMultipleMetadata_ExportStringsAsObjects());
  694. var export = container.GetExport<ExportWithMultipleMetadata_ExportStringsAsObjects, IObjectView_AsStrings>();
  695. Assert.IsNotNull(export);
  696. Assert.IsNotNull(export.Metadata);
  697. Assert.IsNotNull(export.Metadata.Object);
  698. Assert.AreEqual(2, export.Metadata.Object.Length);
  699. }
  700. [TestMethod]
  701. public void ExportWithMultipleMetadata_ExportStringsAsObjects_With_Null_ShouldDiscoverMetadataAsStrings()
  702. {
  703. var container = ContainerFactory.Create();
  704. container.ComposeParts(new ExportWithMultipleMetadata_ExportStringsAsObjects_WithNull());
  705. var export = container.GetExport<ExportWithMultipleMetadata_ExportStringsAsObjects_WithNull, IObjectView_AsStrings>();
  706. Assert.IsNotNull(export);
  707. Assert.IsNotNull(export.Metadata);
  708. Assert.IsNotNull(export.Metadata.Object);
  709. Assert.AreEqual(3, export.Metadata.Object.Length);
  710. }
  711. [TestMethod]
  712. public void ExportWithMultipleMetadata_ExportIntsAsObjects_ShouldDiscoverMetadataAsInts()
  713. {
  714. var container = ContainerFactory.Create();
  715. container.ComposeParts(new ExportWithMultipleMetadata_ExportIntsAsObjects());
  716. var export = container.GetExport<ExportWithMultipleMetadata_ExportIntsAsObjects, IObjectView_AsInts>();
  717. Assert.IsNotNull(export);
  718. Assert.IsNotNull(export.Metadata);
  719. Assert.IsNotNull(export.Metadata.Object);
  720. Assert.AreEqual(2, export.Metadata.Object.Length);
  721. }
  722. [TestMethod]
  723. public void ExportWithMultipleMetadata_ExportIntsAsObjects_With_Null_ShouldDiscoverMetadataAsObjects()
  724. {
  725. var container = ContainerFactory.Create();
  726. container.ComposeParts(new ExportWithMultipleMetadata_ExportIntsAsObjects_WithNull());
  727. var exports = container.GetExports<ExportWithMultipleMetadata_ExportIntsAsObjects_WithNull, IObjectView_AsInts>();
  728. Assert.IsFalse(exports.Any());
  729. var export = container.GetExport<ExportWithMultipleMetadata_ExportIntsAsObjects_WithNull, IObjectView>();
  730. Assert.IsNotNull(export.Metadata);
  731. Assert.IsNotNull(export.Metadata.Object);
  732. Assert.AreEqual(3, export.Metadata.Object.Length);
  733. }
  734. [MetadataAttribute]
  735. [AttributeUsage(AttributeTargets.Class, AllowMultiple = true)]
  736. public class OrderAttribute : Attribute
  737. {
  738. public string Before { get; set; }
  739. public string After { get; set; }
  740. }
  741. public interface IOrderMetadataView
  742. {
  743. string[] Before { get; }
  744. string[] After { get; }
  745. }
  746. [Export]
  747. [Order(Before = "Step3")]
  748. [Order(Before = "Step2")]
  749. public class OrderedItemBeforesOnly
  750. {
  751. }
  752. [TestMethod]
  753. public void ExportWithMultipleMetadata_ExportStringsAndNulls_ThroughMetadataAttributes()
  754. {
  755. var container = ContainerFactory.Create();
  756. container.ComposeParts(new OrderedItemBeforesOnly());
  757. var export = container.GetExport<OrderedItemBeforesOnly, IOrderMetadataView>();
  758. Assert.IsNotNull(export);
  759. Assert.IsNotNull(export.Metadata);
  760. Assert.IsNotNull(export.Metadata.Before);
  761. Assert.IsNotNull(export.Metadata.After);
  762. Assert.AreEqual(2, export.Metadata.Before.Length);
  763. Assert.AreEqual(2, export.Metadata.After.Length);
  764. Assert.IsNotNull(export.Metadata.Before[0]);
  765. Assert.IsNotNull(export.Metadata.Before[1]);
  766. Assert.IsNull(export.Metadata.After[0]);
  767. Assert.IsNull(export.Metadata.After[1]);
  768. }
  769. [MetadataAttribute]
  770. [AttributeUsage(AttributeTargets.Class, AllowMultiple = true)]
  771. public class DataTypeAttribute : Attribute
  772. {
  773. public Type Type { get; set; }
  774. }
  775. public interface ITypesMetadataView
  776. {
  777. Type[] Type { get; }
  778. }
  779. [Export]
  780. [DataType(Type = typeof(int))]
  781. [DataType(Type = typeof(string))]
  782. public class ItemWithTypeExports
  783. {
  784. }
  785. [Export]
  786. [DataType(Type = typeof(int))]
  787. [DataType(Type = typeof(string))]
  788. [DataType(Type = null)]
  789. public class ItemWithTypeExports_WithNulls
  790. {
  791. }
  792. [Export]
  793. [DataType(Type = null)]
  794. [DataType(Type = null)]
  795. [DataType(Type = null)]
  796. public class ItemWithTypeExports_WithAllNulls
  797. {
  798. }
  799. [TestMethod]
  800. public void ExportWithMultipleMetadata_ExportTypes()
  801. {
  802. var container = ContainerFactory.Create();
  803. container.ComposeParts(new ItemWithTypeExports());
  804. var export = container.GetExport<ItemWithTypeExports, ITypesMetadataView>();
  805. Assert.IsNotNull(export.Metadata);
  806. Assert.IsNotNull(export.Metadata.Type);
  807. Assert.AreEqual(2, export.Metadata.Type.Length);
  808. }
  809. [TestMethod]
  810. public void ExportWithMultipleMetadata_ExportTypes_WithNulls()
  811. {
  812. var container = ContainerFactory.Create();
  813. container.ComposeParts(new ItemWithTypeExports_WithNulls());
  814. var export = container.GetExport<ItemWithTypeExports_WithNulls, ITypesMetadataView>();
  815. Assert.IsNotNull(export.Metadata);
  816. Assert.IsNotNull(export.Metadata.Type);
  817. Assert.AreEqual(3, export.Metadata.Type.Length);
  818. }
  819. [TestMethod]
  820. public void ExportWithMultipleMetadata_ExportTypes_WithAllNulls()
  821. {
  822. var container = ContainerFactory.Create();
  823. container.ComposeParts(new ItemWithTypeExports_WithAllNulls());
  824. var export = container.GetExport<ItemWithTypeExports_WithAllNulls, ITypesMetadataView>();
  825. Assert.IsNotNull(export.Metadata);
  826. Assert.IsNotNull(export.Metadata.Type);
  827. Assert.AreEqual(3, export.Metadata.Type.Length);
  828. Assert.IsNull(export.Metadata.Type[0]);
  829. Assert.IsNull(export.Metadata.Type[1]);
  830. Assert.IsNull(export.Metadata.Type[2]);
  831. }
  832. [Export]
  833. [ExportMetadata(null, "ValueOfNullKey")]
  834. public class ClassWithNullMetadataKey
  835. {
  836. }
  837. [TestMethod]
  838. public void ExportMetadataWithNullKey_ShouldUseEmptyString()
  839. {
  840. var nullMetadataCatalog = CatalogFactory.CreateAttributed(typeof(ClassWithNullMetadataKey));
  841. var nullMetadataExport = nullMetadataCatalog.Parts.Single().ExportDefinitions.Single();
  842. Assert.IsTrue(nullMetadataExport.Metadata.ContainsKey(string.Empty));
  843. Assert.AreEqual("ValueOfNullKey", nullMetadataExport.Metadata[string.Empty]);
  844. }
  845. }
  846. // Tests for metadata issues on export
  847. [Export]
  848. [ExportMetadata("foo", "bar1", IsMultiple = true)]
  849. [ExportMetadata("foo", "bar2", IsMultiple = true)]
  850. [ExportMetadata("acme", "acmebar", IsMultiple = true)]
  851. [ExportMetadata("acme", 2.0, IsMultiple = true)]
  852. [ExportMetadata("hello", "world")]
  853. [GoodStrongMetadata]
  854. public class MyExporterWithValidMetadata
  855. {
  856. [Export("ContractForValidMetadata")]
  857. [ExportMetadata("bar", "foo1", IsMultiple = true)]
  858. [ExportMetadata("bar", "foo2", IsMultiple = true)]
  859. [ExportMetadata("stuff", "acmebar", IsMultiple = true)]
  860. [ExportMetadata("stuff", 2.0, IsMultiple = true)]
  861. [ExportMetadata("world", "hello")] // the order of the attribute should not affect the result
  862. [GoodStrongMetadata]
  863. public double DoSomething() { return 0.618; }
  864. }
  865. [AttributeUsage(AttributeTargets.All, AllowMultiple = false)]
  866. [MetadataAttribute]
  867. public class GoodStrongMetadata : Attribute
  868. {
  869. public string GoodOne2 { get { return "GoodOneValue2"; } }
  870. public string ConflictedOne1 { get { return "ConflictedOneValue1"; } }
  871. public string ConflictedOne2 { get { return "ConflictedOneValue2"; } }
  872. }
  873. // Tests for metadata as part of contract
  874. public interface IMyExporter { }
  875. [Export]
  876. [Export(typeof(IMyExporter))]
  877. public class MyExporterWithNoMetadata : IMyExporter
  878. {
  879. }
  880. [Export]
  881. [Export(typeof(IMyExporter))]
  882. [ExportMetadata("Foo", "Bar")]
  883. public class MyExporterWithMetadata : IMyExporter
  884. {
  885. }
  886. public interface IMetadataFoo
  887. {
  888. string Foo { get; }
  889. }
  890. public interface IMetadataBar
  891. {
  892. string Bar { get; }
  893. }
  894. [Export]
  895. public class MyImporterWithExport
  896. {
  897. [Import(typeof(MyExporterWithNoMetadata))]
  898. public Lazy<MyExporterWithNoMetadata, IMetadataFoo> ValueInfo { get; set; }
  899. }
  900. [Export]
  901. public class SingleImportWithAllowDefault
  902. {
  903. [Import("Import", AllowDefault = true)]
  904. public Lazy<object> Import { get; set; }
  905. }
  906. [Export]
  907. public class SingleImport
  908. {
  909. [Import("Import")]
  910. public Lazy<object> Import { get; set; }
  911. }
  912. public interface IFooMetadataView
  913. {
  914. string Foo { get; }
  915. }
  916. [Export]
  917. public class MyImporterWithExportCollection
  918. {
  919. [ImportMany(typeof(MyExporterWithNoMetadata))]
  920. public IEnumerable<Lazy<MyExporterWithNoMetadata, IFooMetadataView>> ValueInfoCol { get; set; }
  921. }
  922. [Export]
  923. public class MyImporterWithExportForSelectiveImport
  924. {
  925. [Import]
  926. public Lazy<IMyExporter, IFooMetadataView> ValueInfo { get; set; }
  927. }
  928. [Export]
  929. public class MyImporterWithExportCollectionForSelectiveImport
  930. {
  931. [ImportMany]
  932. public Collection<Lazy<IMyExporter, IFooMetadataView>> ValueInfoCol { get; set; }
  933. }
  934. public interface IMetadataView
  935. {
  936. string Foo { get; }
  937. [System.ComponentModel.DefaultValue(null)]
  938. string OptionalFoo { get; }
  939. }
  940. [Export]
  941. [ExportMetadata("Foo", "fooValue3")]
  942. [ExportMetadata("OptionalFoo", 42)]
  943. public class OptionalFooIsInt { }
  944. [Export]
  945. public class MyImporterWithExportStronglyTypedMetadata
  946. {
  947. [Import]
  948. public Lazy<IMyExporter, IMetadataView> ValueInfo { get; set; }
  949. }
  950. [Export]
  951. public class MyImporterWithExportCollectionStronglyTypedMetadata
  952. {
  953. [ImportMany]
  954. public Collection<Lazy<IMyExporter, IMetadataView>> ValueInfoCol { get; set; }
  955. }
  956. public class MyExporterWithFullMetadata
  957. {
  958. [Export("MyStringContract")]
  959. public string String1 { get { return "String1"; } }
  960. [Export("MyStringContract")]
  961. [ExportMetadata("Foo", "fooValue")]
  962. public string String2 { get { return "String2"; } }
  963. [Export("MyStringContract")]
  964. [ExportMetadata("Bar", "barValue")]
  965. public string String3 { get { return "String3"; } }
  966. [Export("MyStringContract")]
  967. [ExportMetadata("Foo", "fooValue")]
  968. [ExportMetadata("Bar", "barValue")]
  969. public string String4 { get { return "String4"; } }
  970. }
  971. [MetadataAttribute]
  972. [AttributeUsage(AttributeTargets.All, AllowMultiple = true)]
  973. public class MyOption : Attribute
  974. {
  975. public MyOption(string name, object value)