1 // -----------------------------------------------------------------------
\r
2 // Copyright (c) Microsoft Corporation. All rights reserved.
\r
3 // -----------------------------------------------------------------------
\r
6 using System.ComponentModel.Composition;
\r
7 using Microsoft.VisualStudio.TestTools.UnitTesting;
\r
8 using System.ComponentModel.Composition.UnitTesting;
\r
9 using System.ComponentModel.Composition.Factories;
\r
10 using System.ComponentModel.Composition.Primitives;
\r
12 namespace Tests.Integration
\r
15 public class CompositionContainerAttributedModelCycleTests
\r
17 // There are nine possible scenarios that cause a part to have a dependency on another part, some of which
\r
18 // are legal and some not. For example, below, is not legal for a part, A, to have a prerequisite dependency
\r
19 // on a part, B, which has also has a prerequisite dependency on A. In contrast, however, it is legal for
\r
20 // part A and B to have a non-prerequisite (Post) dependency on each other.
\r
22 // ------------------------------
\r
24 // | | Pre | Post | None |
\r
25 // |--------|-----|------|------|
\r
26 // | Pre | X | X | √ |
\r
27 // | A Post | X | √ | √ |
\r
28 // | None | √ | √ | √ |
\r
29 // ------------------------------
\r
33 public void APrerequisiteDependsOnBPrerequisite_ShouldThrowComposition()
\r
35 AssertCycle(typeof(APrerequisiteDependsOnBPrerequisite),
\r
36 typeof(BPrerequisiteDependsOnAPrerequisite));
\r
40 public void APrerequisiteDependsOnBPost_ShouldThrowComposition()
\r
42 AssertCycle(typeof(APrerequisiteDependsOnBPost),
\r
43 typeof(BPostDependsOnAPrerequisite));
\r
47 public void APrerequisiteDependsOnBNone_ShouldNotThrow()
\r
49 AssertNotCycle(typeof(APrerequisiteDependsOnBNone),
\r
54 public void APostDependsOnBPrerequisite_ShouldThrowComposition()
\r
56 AssertCycle(typeof(APostDependsOnBPrerequisite),
\r
57 typeof(BPrerequisiteDependsOnAPost));
\r
61 public void APostDependsOnBPost_ShouldNotThrow()
\r
63 AssertNotCycle(typeof(APostDependsOnBPost),
\r
64 typeof(BPostDependsOnAPost));
\r
68 public void APostDependsOnBNone_ShouldNotThrow()
\r
70 AssertNotCycle(typeof(APostDependsOnBNone),
\r
75 public void BPrerequisiteDependsOnANone_ShouldNotThrow()
\r
77 AssertNotCycle(typeof(ANone),
\r
78 typeof(BPrerequisiteDependsOnANone));
\r
82 public void BPostDependsOnANone_ShouldNotThrow()
\r
84 AssertNotCycle(typeof(ANone),
\r
85 typeof(BPostDependsOnANone));
\r
89 public void ANoneWithBNone_ShouldNotThrow()
\r
91 AssertNotCycle(typeof(ANone),
\r
96 public void PartWithHasPrerequisteImportThatIsInAPostCycle_ShouldNotThrow()
\r
98 AssertNotCycle(typeof(PartWithHasPrerequisteImportThatIsInAPostCycle)
\r
99 , typeof(APostDependsOnBPost), typeof(BPostDependsOnAPost));
\r
102 private static void AssertCycle(params Type[] types)
\r
104 foreach (Type type in types)
\r
106 var export = GetExport(type, types);
\r
108 CompositionAssert.ThrowsError(ErrorId.ImportEngine_PartCannotGetExportedValue, () =>
\r
110 var value = export.Value;
\r
115 private static void AssertNotCycle(params Type[] types)
\r
117 foreach (Type type in types)
\r
119 var export = GetExport(type, types);
\r
121 Assert.IsInstanceOfType(export.Value, type);
\r
125 private static Lazy<object, object> GetExport(Type type, Type[] partTypes)
\r
127 var container = ContainerFactory.CreateWithAttributedCatalog(partTypes);
\r
129 return container.GetExports(type, null, null).Single();
\r
133 public class APrerequisiteDependsOnBPrerequisite
\r
135 [ImportingConstructor]
\r
136 public APrerequisiteDependsOnBPrerequisite(BPrerequisiteDependsOnAPrerequisite b)
\r
142 public class BPrerequisiteDependsOnAPrerequisite
\r
144 [ImportingConstructor]
\r
145 public BPrerequisiteDependsOnAPrerequisite(APrerequisiteDependsOnBPrerequisite a)
\r
152 public class APrerequisiteDependsOnBPost
\r
154 [ImportingConstructor]
\r
155 public APrerequisiteDependsOnBPost(BPostDependsOnAPrerequisite b)
\r
161 public class BPostDependsOnAPrerequisite
\r
164 public APrerequisiteDependsOnBPost A
\r
172 public class APrerequisiteDependsOnBNone
\r
174 [ImportingConstructor]
\r
175 public APrerequisiteDependsOnBNone(BNone b)
\r
192 public class APostDependsOnBPrerequisite
\r
195 public BPrerequisiteDependsOnAPost B
\r
203 public class BPrerequisiteDependsOnAPost
\r
205 [ImportingConstructor]
\r
206 public BPrerequisiteDependsOnAPost(APostDependsOnBPrerequisite a)
\r
213 public class APostDependsOnBPost
\r
216 public BPostDependsOnAPost B
\r
224 public class BPostDependsOnAPost
\r
227 public APostDependsOnBPost A
\r
235 public class APostDependsOnBNone
\r
246 public class BPrerequisiteDependsOnANone
\r
248 [ImportingConstructor]
\r
249 public BPrerequisiteDependsOnANone(ANone a)
\r
255 public class BPostDependsOnANone
\r
266 public class PartWithHasPrerequisteImportThatIsInAPostCycle
\r
268 [ImportingConstructor]
\r
269 public PartWithHasPrerequisteImportThatIsInAPostCycle(APostDependsOnBPost a)
\r