1 // -----------------------------------------------------------------------
\r
2 // Copyright (c) Microsoft Corporation. All rights reserved.
\r
3 // -----------------------------------------------------------------------
\r
5 using System.ComponentModel.Composition.Factories;
\r
6 using System.ComponentModel.Composition.Hosting;
\r
7 using System.ComponentModel.Composition.Primitives;
\r
8 using System.Reflection;
\r
9 using Microsoft.Internal;
\r
10 using Microsoft.VisualStudio.TestTools.UnitTesting;
\r
11 using System.Collections.Generic;
\r
13 using System.UnitTesting;
\r
14 using System.Threading;
\r
16 namespace System.ComponentModel.Composition.ReflectionModel
\r
19 public class ReflectionComposablePartDefinitionTests
\r
21 private ReflectionComposablePartDefinition CreateReflectionPartDefinition(
\r
22 Lazy<Type> partType,
\r
23 bool requiresDisposal,
\r
24 Func<IEnumerable<ImportDefinition>> imports,
\r
25 Func<IEnumerable<ExportDefinition>>exports,
\r
26 IDictionary<string, object> metadata,
\r
27 ICompositionElement origin)
\r
29 return (ReflectionComposablePartDefinition)ReflectionModelServices.CreatePartDefinition(partType, requiresDisposal,
\r
30 new Lazy<IEnumerable<ImportDefinition>>(imports, false),
\r
31 new Lazy<IEnumerable<ExportDefinition>>(exports, false),
\r
32 metadata.AsLazy(), origin);
\r
36 public void Constructor()
\r
38 Type expectedType = typeof(TestPart);
\r
39 Lazy<Type> expectedLazyType = expectedType.AsLazy();
\r
40 IDictionary<string, object> expectedMetadata = new Dictionary<string, object>();
\r
41 expectedMetadata["Key1"] = 1;
\r
42 expectedMetadata["Key2"] = "Value2";
\r
44 IEnumerable<ImportDefinition> expectedImports = CreateImports(expectedType);
\r
45 IEnumerable<ExportDefinition> expectedExports = CreateExports(expectedType);
\r
47 ICompositionElement expectedOrigin = new MockOrigin();
\r
49 ReflectionComposablePartDefinition definition = CreateReflectionPartDefinition(
\r
52 () => expectedImports,
\r
53 () => expectedExports,
\r
57 Assert.AreSame(expectedType, definition.GetPartType());
\r
58 Assert.IsTrue(definition.Metadata.Keys.SequenceEqual(expectedMetadata.Keys));
\r
59 Assert.IsTrue(definition.Metadata.Values.SequenceEqual(expectedMetadata.Values));
\r
60 Assert.IsTrue(definition.ExportDefinitions.SequenceEqual(expectedExports.Cast<ExportDefinition>()));
\r
61 Assert.IsTrue(definition.ImportDefinitions.SequenceEqual(expectedImports.Cast<ImportDefinition>()));
\r
62 Assert.AreSame(expectedOrigin, ((ICompositionElement)definition).Origin);
\r
63 Assert.IsNotNull(((ICompositionElement)definition).DisplayName);
\r
64 Assert.IsFalse(definition.IsDisposalRequired);
\r
68 public void Constructor_DisposablePart()
\r
70 Type expectedType = typeof(TestPart);
\r
71 Lazy<Type> expectedLazyType = expectedType.AsLazy();
\r
72 IDictionary<string, object> expectedMetadata = new Dictionary<string, object>();
\r
73 expectedMetadata["Key1"] = 1;
\r
74 expectedMetadata["Key2"] = "Value2";
\r
76 IEnumerable<ImportDefinition> expectedImports = CreateImports(expectedType);
\r
77 IEnumerable<ExportDefinition> expectedExports = CreateExports(expectedType);
\r
79 ICompositionElement expectedOrigin = new MockOrigin();
\r
81 ReflectionComposablePartDefinition definition = CreateReflectionPartDefinition(
\r
84 () => expectedImports,
\r
85 () => expectedExports,
\r
89 Assert.AreSame(expectedType, definition.GetPartType());
\r
90 Assert.IsTrue(definition.Metadata.Keys.SequenceEqual(expectedMetadata.Keys));
\r
91 Assert.IsTrue(definition.Metadata.Values.SequenceEqual(expectedMetadata.Values));
\r
92 Assert.IsTrue(definition.ExportDefinitions.SequenceEqual(expectedExports.Cast<ExportDefinition>()));
\r
93 Assert.IsTrue(definition.ImportDefinitions.SequenceEqual(expectedImports.Cast<ImportDefinition>()));
\r
94 Assert.AreSame(expectedOrigin, ((ICompositionElement)definition).Origin);
\r
95 Assert.IsNotNull(((ICompositionElement)definition).DisplayName);
\r
96 Assert.IsTrue(definition.IsDisposalRequired);
\r
100 public void CreatePart()
\r
102 Type expectedType = typeof(TestPart);
\r
103 Lazy<Type> expectedLazyType = expectedType.AsLazy();
\r
104 IDictionary<string, object> expectedMetadata = new Dictionary<string, object>();
\r
105 expectedMetadata["Key1"] = 1;
\r
106 expectedMetadata["Key2"] = "Value2";
\r
108 IEnumerable<ImportDefinition> expectedImports = CreateImports(expectedType);
\r
109 IEnumerable<ExportDefinition> expectedExports = CreateExports(expectedType);
\r
111 ICompositionElement expectedOrigin = new MockOrigin();
\r
113 ReflectionComposablePartDefinition definition = CreateReflectionPartDefinition(
\r
116 () => expectedImports,
\r
117 () => expectedExports,
\r
121 var part = definition.CreatePart();
\r
122 Assert.IsNotNull(part);
\r
123 Assert.IsFalse(part is IDisposable);
\r
127 public void CreatePart_Disposable()
\r
129 Type expectedType = typeof(TestPart);
\r
130 Lazy<Type> expectedLazyType = expectedType.AsLazy();
\r
131 IDictionary<string, object> expectedMetadata = new Dictionary<string, object>();
\r
132 expectedMetadata["Key1"] = 1;
\r
133 expectedMetadata["Key2"] = "Value2";
\r
135 IEnumerable<ImportDefinition> expectedImports = CreateImports(expectedType);
\r
136 IEnumerable<ExportDefinition> expectedExports = CreateExports(expectedType);
\r
138 ICompositionElement expectedOrigin = new MockOrigin();
\r
140 ReflectionComposablePartDefinition definition = CreateReflectionPartDefinition(
\r
143 () => expectedImports,
\r
144 () => expectedExports,
\r
148 var part = definition.CreatePart();
\r
149 Assert.IsNotNull(part);
\r
150 Assert.IsTrue(part is IDisposable);
\r
154 public void CreatePart_DoesntLoadType()
\r
156 Type expectedType = typeof(TestPart);
\r
157 Lazy<Type> expectedLazyType = new Lazy<Type>(() => { Assert.Fail("Part should not be loaded"); return null; });
\r
158 IDictionary<string, object> expectedMetadata = new Dictionary<string, object>();
\r
159 expectedMetadata["Key1"] = 1;
\r
160 expectedMetadata["Key2"] = "Value2";
\r
162 IEnumerable<ImportDefinition> expectedImports = CreateImports(expectedType);
\r
163 IEnumerable<ExportDefinition> expectedExports = CreateExports(expectedType);
\r
165 ICompositionElement expectedOrigin = new MockOrigin();
\r
167 ReflectionComposablePartDefinition definition = CreateReflectionPartDefinition(
\r
170 () => expectedImports,
\r
171 () => expectedExports,
\r
175 var part = definition.CreatePart();
\r
176 Assert.IsNotNull(part);
\r
177 Assert.IsTrue(part is IDisposable);
\r
181 public void Constructor_NullMetadata_ShouldSetMetadataPropertyToEmpty()
\r
183 ReflectionComposablePartDefinition definition = CreateEmptyDefinition(typeof(object), typeof(object).GetConstructors().First(), null, new MockOrigin());
\r
184 Assert.IsNotNull(definition.Metadata);
\r
185 Assert.AreEqual(0, definition.Metadata.Count);
\r
189 public void Constructor_NullOrigin_ShouldSetOriginPropertyToNull()
\r
191 ReflectionComposablePartDefinition definition = CreateEmptyDefinition(typeof(object), typeof(object).GetConstructors().First(), MetadataServices.EmptyMetadata, null);
\r
192 Assert.IsNotNull(((ICompositionElement)definition).DisplayName);
\r
193 Assert.IsNull(((ICompositionElement)definition).Origin);
\r
197 public void ImportaAndExports_CreatorsShouldBeCalledLazilyAndOnce()
\r
199 Type expectedType = typeof(TestPart);
\r
201 IEnumerable<ImportDefinition> expectedImports = CreateImports(expectedType);
\r
202 IEnumerable<ExportDefinition> expectedExports = CreateExports(expectedType);
\r
204 bool importsCreatorCalled = false;
\r
205 Func<IEnumerable<ImportDefinition>> importsCreator = () =>
\r
207 Assert.IsFalse(importsCreatorCalled);
\r
208 importsCreatorCalled = true;
\r
209 return expectedImports.Cast<ImportDefinition>();
\r
212 bool exportsCreatorCalled = false;
\r
213 Func<IEnumerable<ExportDefinition>> exportsCreator = () =>
\r
215 Assert.IsFalse(exportsCreatorCalled);
\r
216 exportsCreatorCalled = true;
\r
217 return expectedExports.Cast<ExportDefinition>();
\r
220 ReflectionComposablePartDefinition definition = CreateReflectionPartDefinition(
\r
221 expectedType.AsLazy(),
\r
228 IEnumerable<ExportDefinition> exports;
\r
229 Assert.IsFalse(exportsCreatorCalled);
\r
230 exports = definition.ExportDefinitions;
\r
231 Assert.IsTrue(exportsCreatorCalled);
\r
232 exports = definition.ExportDefinitions;
\r
235 IEnumerable<ImportDefinition> imports;
\r
236 Assert.IsFalse(importsCreatorCalled);
\r
237 imports = definition.ImportDefinitions;
\r
238 Assert.IsTrue(importsCreatorCalled);
\r
239 imports = definition.ImportDefinitions;
\r
243 public void ICompositionElementDisplayName_ShouldReturnTypeDisplayName()
\r
245 var expectations = Expectations.GetAttributedTypes();
\r
246 foreach (var e in expectations)
\r
248 var definition = (ICompositionElement)CreateEmptyDefinition(e, null, null, null);
\r
250 Assert.AreEqual(e.GetDisplayName(), definition.DisplayName);
\r
255 public void ToString_ShouldReturnICompositionElementDisplayName()
\r
257 var expectations = Expectations.GetAttributedTypes();
\r
258 foreach (var e in expectations)
\r
260 var definition = (ICompositionElement)CreateEmptyDefinition(e, null, null, null);
\r
262 Assert.AreEqual(definition.DisplayName, definition.ToString());
\r
266 private ReflectionComposablePartDefinition CreateEmptyDefinition(Type type, ConstructorInfo constructor, IDictionary<string, object> metadata, ICompositionElement origin)
\r
268 return (ReflectionComposablePartDefinition)ReflectionModelServices.CreatePartDefinition(
\r
269 (type != null) ? type.AsLazy() : null,
\r
271 Enumerable.Empty<ImportDefinition>().AsLazy(),
\r
272 Enumerable.Empty<ExportDefinition>().AsLazy(),
\r
277 private static List<ImportDefinition> CreateImports(Type type)
\r
279 List<ImportDefinition> imports = new List<ImportDefinition>();
\r
280 foreach (PropertyInfo property in type.GetProperties())
\r
282 imports.Add(new ReflectionMemberImportDefinition(new LazyMemberInfo(property), "Contract", (string)null, new KeyValuePair<string, Type>[] { new KeyValuePair<string, Type>("Key1", typeof(object)) }, ImportCardinality.ZeroOrOne, true, CreationPolicy.Any, new TypeOrigin(type)));
\r
288 private static List<ExportDefinition> CreateExports(Type type)
\r
290 List<ExportDefinition> exports = new List<ExportDefinition>();
\r
291 foreach (PropertyInfo property in type.GetProperties())
\r
293 exports.Add(ReflectionModelServices.CreateExportDefinition(new LazyMemberInfo(property), "Contract", new Lazy<IDictionary<string, object>>(() => null, false), new TypeOrigin(type)));
\r
299 public class TestPart
\r
302 public string field2;
\r
303 public int Property1 { get; set; }
\r
304 public string Property2 { get; set; }
\r
307 private class TypeOrigin : ICompositionElement
\r
309 private readonly Type _type;
\r
310 private readonly ICompositionElement _orgin;
\r
312 public TypeOrigin(Type type)
\r
317 public TypeOrigin(Type type, ICompositionElement origin)
\r
320 this._orgin = origin;
\r
323 public string DisplayName
\r
327 return this._type.GetDisplayName();
\r
331 public ICompositionElement Origin
\r
335 return this._orgin;
\r
340 private class MockOrigin : ICompositionElement
\r
342 public string DisplayName
\r
344 get { throw new NotImplementedException(); }
\r
347 public ICompositionElement Origin
\r
349 get { throw new NotImplementedException(); }
\r