CompositionContainerAttributedModelCycleTests.cs 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274
  1. // -----------------------------------------------------------------------
  2. // Copyright (c) Microsoft Corporation. All rights reserved.
  3. // -----------------------------------------------------------------------
  4. using System;
  5. using System.Linq;
  6. using System.ComponentModel.Composition;
  7. using Microsoft.VisualStudio.TestTools.UnitTesting;
  8. using System.ComponentModel.Composition.UnitTesting;
  9. using System.ComponentModel.Composition.Factories;
  10. using System.ComponentModel.Composition.Primitives;
  11. namespace Tests.Integration
  12. {
  13. [TestClass]
  14. public class CompositionContainerAttributedModelCycleTests
  15. {
  16. // There are nine possible scenarios that cause a part to have a dependency on another part, some of which
  17. // are legal and some not. For example, below, is not legal for a part, A, to have a prerequisite dependency
  18. // on a part, B, which has also has a prerequisite dependency on A. In contrast, however, it is legal for
  19. // part A and B to have a non-prerequisite (Post) dependency on each other.
  20. //
  21. // ------------------------------
  22. // | | B |
  23. // | | Pre | Post | None |
  24. // |--------|-----|------|------|
  25. // | Pre | X | X | √ |
  26. // | A Post | X | √ | √ |
  27. // | None | √ | √ | √ |
  28. // ------------------------------
  29. //
  30. [TestMethod]
  31. public void APrerequisiteDependsOnBPrerequisite_ShouldThrowComposition()
  32. {
  33. AssertCycle(typeof(APrerequisiteDependsOnBPrerequisite),
  34. typeof(BPrerequisiteDependsOnAPrerequisite));
  35. }
  36. [TestMethod]
  37. public void APrerequisiteDependsOnBPost_ShouldThrowComposition()
  38. {
  39. AssertCycle(typeof(APrerequisiteDependsOnBPost),
  40. typeof(BPostDependsOnAPrerequisite));
  41. }
  42. [TestMethod]
  43. public void APrerequisiteDependsOnBNone_ShouldNotThrow()
  44. {
  45. AssertNotCycle(typeof(APrerequisiteDependsOnBNone),
  46. typeof(BNone));
  47. }
  48. [TestMethod]
  49. public void APostDependsOnBPrerequisite_ShouldThrowComposition()
  50. {
  51. AssertCycle(typeof(APostDependsOnBPrerequisite),
  52. typeof(BPrerequisiteDependsOnAPost));
  53. }
  54. [TestMethod]
  55. public void APostDependsOnBPost_ShouldNotThrow()
  56. {
  57. AssertNotCycle(typeof(APostDependsOnBPost),
  58. typeof(BPostDependsOnAPost));
  59. }
  60. [TestMethod]
  61. public void APostDependsOnBNone_ShouldNotThrow()
  62. {
  63. AssertNotCycle(typeof(APostDependsOnBNone),
  64. typeof(BNone));
  65. }
  66. [TestMethod]
  67. public void BPrerequisiteDependsOnANone_ShouldNotThrow()
  68. {
  69. AssertNotCycle(typeof(ANone),
  70. typeof(BPrerequisiteDependsOnANone));
  71. }
  72. [TestMethod]
  73. public void BPostDependsOnANone_ShouldNotThrow()
  74. {
  75. AssertNotCycle(typeof(ANone),
  76. typeof(BPostDependsOnANone));
  77. }
  78. [TestMethod]
  79. public void ANoneWithBNone_ShouldNotThrow()
  80. {
  81. AssertNotCycle(typeof(ANone),
  82. typeof(BNone));
  83. }
  84. [TestMethod]
  85. public void PartWithHasPrerequisteImportThatIsInAPostCycle_ShouldNotThrow()
  86. {
  87. AssertNotCycle(typeof(PartWithHasPrerequisteImportThatIsInAPostCycle)
  88. , typeof(APostDependsOnBPost), typeof(BPostDependsOnAPost));
  89. }
  90. private static void AssertCycle(params Type[] types)
  91. {
  92. foreach (Type type in types)
  93. {
  94. var export = GetExport(type, types);
  95. CompositionAssert.ThrowsError(ErrorId.ImportEngine_PartCannotGetExportedValue, () =>
  96. {
  97. var value = export.Value;
  98. });
  99. }
  100. }
  101. private static void AssertNotCycle(params Type[] types)
  102. {
  103. foreach (Type type in types)
  104. {
  105. var export = GetExport(type, types);
  106. Assert.IsInstanceOfType(export.Value, type);
  107. }
  108. }
  109. private static Lazy<object, object> GetExport(Type type, Type[] partTypes)
  110. {
  111. var container = ContainerFactory.CreateWithAttributedCatalog(partTypes);
  112. return container.GetExports(type, null, null).Single();
  113. }
  114. [Export]
  115. public class APrerequisiteDependsOnBPrerequisite
  116. {
  117. [ImportingConstructor]
  118. public APrerequisiteDependsOnBPrerequisite(BPrerequisiteDependsOnAPrerequisite b)
  119. {
  120. }
  121. }
  122. [Export]
  123. public class BPrerequisiteDependsOnAPrerequisite
  124. {
  125. [ImportingConstructor]
  126. public BPrerequisiteDependsOnAPrerequisite(APrerequisiteDependsOnBPrerequisite a)
  127. {
  128. }
  129. }
  130. [Export]
  131. public class APrerequisiteDependsOnBPost
  132. {
  133. [ImportingConstructor]
  134. public APrerequisiteDependsOnBPost(BPostDependsOnAPrerequisite b)
  135. {
  136. }
  137. }
  138. [Export]
  139. public class BPostDependsOnAPrerequisite
  140. {
  141. [Import]
  142. public APrerequisiteDependsOnBPost A
  143. {
  144. get;
  145. set;
  146. }
  147. }
  148. [Export]
  149. public class APrerequisiteDependsOnBNone
  150. {
  151. [ImportingConstructor]
  152. public APrerequisiteDependsOnBNone(BNone b)
  153. {
  154. }
  155. }
  156. [Export]
  157. public class BNone
  158. {
  159. }
  160. [Export]
  161. public class ANone
  162. {
  163. }
  164. [Export]
  165. public class APostDependsOnBPrerequisite
  166. {
  167. [Import]
  168. public BPrerequisiteDependsOnAPost B
  169. {
  170. get;
  171. set;
  172. }
  173. }
  174. [Export]
  175. public class BPrerequisiteDependsOnAPost
  176. {
  177. [ImportingConstructor]
  178. public BPrerequisiteDependsOnAPost(APostDependsOnBPrerequisite a)
  179. {
  180. }
  181. }
  182. [Export]
  183. public class APostDependsOnBPost
  184. {
  185. [Import]
  186. public BPostDependsOnAPost B
  187. {
  188. get;
  189. set;
  190. }
  191. }
  192. [Export]
  193. public class BPostDependsOnAPost
  194. {
  195. [Import]
  196. public APostDependsOnBPost A
  197. {
  198. get;
  199. set;
  200. }
  201. }
  202. [Export]
  203. public class APostDependsOnBNone
  204. {
  205. [Import]
  206. public BNone B
  207. {
  208. get;
  209. set;
  210. }
  211. }
  212. [Export]
  213. public class BPrerequisiteDependsOnANone
  214. {
  215. [ImportingConstructor]
  216. public BPrerequisiteDependsOnANone(ANone a)
  217. {
  218. }
  219. }
  220. [Export]
  221. public class BPostDependsOnANone
  222. {
  223. [Import]
  224. public ANone A
  225. {
  226. get;
  227. set;
  228. }
  229. }
  230. [Export]
  231. public class PartWithHasPrerequisteImportThatIsInAPostCycle
  232. {
  233. [ImportingConstructor]
  234. public PartWithHasPrerequisteImportThatIsInAPostCycle(APostDependsOnBPost a)
  235. {
  236. }
  237. }
  238. }
  239. }