Implement MachineKey.Protect and MachineKey.Unprotect
[mono.git] / mcs / class / System.ComponentModel.Composition / Tests / ComponentModelUnitTest / System / ComponentModel / Composition / ReflectionModel / ReflectionComposablePartTests.cs
1 // -----------------------------------------------------------------------\r
2 // Copyright (c) Microsoft Corporation.  All rights reserved.\r
3 // -----------------------------------------------------------------------\r
4 using System;\r
5 using System.ComponentModel.Composition;\r
6 using System.Linq;\r
7 using Microsoft.VisualStudio.TestTools.UnitTesting;\r
8 using System.UnitTesting;\r
9 using System.ComponentModel.Composition.UnitTesting;\r
10 using System.ComponentModel.Composition.Factories;\r
11 using System.Collections.Generic;\r
12 using Microsoft.Internal;\r
13 using System.ComponentModel.Composition.Hosting;\r
14 using System.ComponentModel.Composition.Primitives;\r
15 using System.ComponentModel.Composition.AttributedModel;\r
16 using System.ComponentModel.Composition.Diagnostics;\r
17 using System.Diagnostics;\r
18 using System.ComponentModel.Composition.Extensibility;\r
19 \r
20 namespace System.ComponentModel.Composition.ReflectionModel\r
21 {\r
22     [TestClass]\r
23     public class ReflectionComposablePartTests\r
24     {\r
25         [TestMethod]\r
26         public void Constructor1_DefinitionAsDefinitionArgument_ShouldSetOriginProperty()\r
27         {\r
28             var expectations = Expectations.GetAttributedDefinitions();\r
29 \r
30             foreach (var e in expectations)\r
31             {\r
32                 var definition = (ICompositionElement)new ReflectionComposablePart(e);\r
33 \r
34                 Assert.AreSame(e, definition.Origin);\r
35             }\r
36         }\r
37 \r
38         [TestMethod]\r
39         public void Constructor1_NullAsDefinitionArgument_ShouldThrowArgumentNull()\r
40         {\r
41             ExceptionAssert.ThrowsArgument<ArgumentNullException>("definition", () =>\r
42             {\r
43                 new ReflectionComposablePart((ReflectionComposablePartDefinition)null);\r
44             });\r
45         }\r
46 \r
47         [TestMethod]\r
48         public void Constructor2_NullAsAttributedPartArgument_ShouldThrowArgumentNull()\r
49         {\r
50             ExceptionAssert.ThrowsArgument<ArgumentNullException>("attributedPart", () =>\r
51             {\r
52                 new ReflectionComposablePart(PartDefinitionFactory.CreateAttributed(), (object)null);\r
53             });\r
54         }\r
55 \r
56         [TestMethod]\r
57         public void Constructor2_ValueTypeAsAttributedPartArgument_ShouldThrowArgument()\r
58         {\r
59             ExceptionAssert.ThrowsArgument<ArgumentException>("attributedPart", () =>\r
60             {\r
61                 new ReflectionComposablePart(PartDefinitionFactory.CreateAttributed(), 42);\r
62             });\r
63         }\r
64 \r
65 \r
66         [TestMethod]\r
67         public void Constructor1_AttributedComposablePartDefintion_ShouldProduceValidObject()\r
68         {\r
69             var definition = PartDefinitionFactory.CreateAttributed(typeof(MyExport));\r
70             var part = new ReflectionComposablePart(definition);\r
71 \r
72             Assert.AreEqual(definition, part.Definition);\r
73             Assert.IsNotNull(part.Metadata);\r
74 \r
75             Assert.IsFalse(part is IDisposable);\r
76         }\r
77 \r
78         [TestMethod]\r
79         public void Constructor1_AttributedComposablePartDefintion_Disposable_ShouldProduceValidObject()\r
80         {\r
81             var definition = PartDefinitionFactory.CreateAttributed(typeof(DisposablePart));\r
82             var part = new DisposableReflectionComposablePart(definition);\r
83 \r
84             Assert.AreEqual(definition, part.Definition);\r
85             Assert.IsNotNull(part.Metadata);\r
86 \r
87             Assert.IsTrue(part is IDisposable);\r
88         }\r
89 \r
90         [TestMethod]\r
91         public void Constructor1_Type_ShouldProduceValidObject()\r
92         {\r
93             var part = new ReflectionComposablePart(PartDefinitionFactory.CreateAttributed(typeof(MyExport)));\r
94         }\r
95 \r
96         [TestMethod]\r
97         public void Constructor1_Object_ShouldProduceValidObject()\r
98         {\r
99             var part = new ReflectionComposablePart(PartDefinitionFactory.CreateAttributed(typeof(MyExport)), new MyExport());\r
100         }\r
101 \r
102         [TestMethod]\r
103         public void Metadata_WhenDisposed_ShouldThrowObjectDisposed()\r
104         {\r
105             var part = CreateDefaultDisposablePart();\r
106             ((IDisposable)part).Dispose();\r
107 \r
108             ExceptionAssert.ThrowsDisposed(part, () =>\r
109             {\r
110                 var metadata = part.Metadata;\r
111             });\r
112         }\r
113 \r
114         [TestMethod]\r
115         public void ImportDefinitions_WhenDisposed_ShouldThrowObjectDisposed()\r
116         {\r
117             var part = CreateDefaultDisposablePart();\r
118             ((IDisposable)part).Dispose();\r
119 \r
120             ExceptionAssert.ThrowsDisposed(part, () =>\r
121             {\r
122                 var definitions = part.ImportDefinitions;\r
123             });\r
124         }\r
125 \r
126         [TestMethod]\r
127         public void ExportDefinitions_WhenDisposed_ShouldThrowObjectDisposed()\r
128         {\r
129             var part = CreateDefaultDisposablePart();\r
130             ((IDisposable)part).Dispose();\r
131 \r
132             ExceptionAssert.ThrowsDisposed(part, () =>\r
133             {\r
134                 var definitions = part.ExportDefinitions;\r
135             });\r
136         }\r
137         [TestMethod]\r
138         public void OnComposed_WhenDisposed_ShouldThrowObjectDisposed()\r
139         {\r
140             var part = CreateDefaultDisposablePart();\r
141             ((IDisposable)part).Dispose();\r
142 \r
143             ExceptionAssert.ThrowsDisposed(part, () =>\r
144             {\r
145                 part.Activate();\r
146             });\r
147         }\r
148 \r
149         [TestMethod]\r
150         public void OnComposed_MissingPostImportsOnInstance_ShouldThrowComposition()\r
151         {\r
152             var part = CreatePart(new MySharedPartExport());\r
153 \r
154             // Dev10:484204 - This used to cause a failure but after we made \r
155             // ReflectionComposablePart internal we needed to back remove this \r
156             // validation for post imports to make declarative composition work.\r
157             //part.Activate().VerifyFailure(CompositionIssueId.ImportNotSetOnPart);\r
158             part.Activate();\r
159         }\r
160 \r
161         [TestMethod]\r
162         public void OnComposed_ProperlyComposed_ShouldSucceed()\r
163         {\r
164             var import = new TrivialImporter();\r
165             var export = new TrivialExporter();\r
166 \r
167             var part = CreatePart(import);\r
168 \r
169             var importDef = part.ImportDefinitions.First();\r
170             part.SetImport(importDef, CreateSimpleExports(export));\r
171             part.Activate();\r
172             Assert.IsTrue(export.done, "OnImportsSatisfied should have been called");\r
173         }\r
174 \r
175         [TestMethod]\r
176         public void OnComposed_UnhandledExceptionThrowInOnImportsSatisfied_ShouldThrowComposablePart()\r
177         {\r
178             var part = CreatePart(typeof(ExceptionDuringINotifyImport));\r
179             var definition = part.ImportDefinitions.First();\r
180             part.SetImport(definition, CreateSimpleExports(21));\r
181 \r
182             CompositionAssert.ThrowsPart<NotImplementedException>(ErrorId.ReflectionModel_PartOnImportsSatisfiedThrewException, RetryMode.DoNotRetry, () =>\r
183             {\r
184                 part.Activate();\r
185             });\r
186         }\r
187 \r
188         [TestMethod]\r
189         public void SetImport_WhenDisposed_ShouldThrowObjectDisposed()\r
190         {\r
191             var part = CreateDefaultDisposablePart();\r
192             var definition = part.ImportDefinitions.First();\r
193 \r
194             ((IDisposable)part).Dispose();\r
195 \r
196             ExceptionAssert.ThrowsDisposed(part, () =>\r
197             {\r
198                 part.SetImport(definition, Enumerable.Empty<Export>());\r
199             });\r
200         }\r
201 \r
202         [TestMethod]\r
203         public void SetImport_NullAsImportDefinitionArgument_ShouldThrowArgumentNull()\r
204         {\r
205             var part = CreateDefaultPart();\r
206 \r
207             ExceptionAssert.ThrowsArgument<ArgumentNullException>("definition", () =>\r
208             {\r
209                 part.SetImport((ImportDefinition)null, Enumerable.Empty<Export>());\r
210             });\r
211         }\r
212 \r
213         [TestMethod]\r
214         public void SetImport_NullAsExportsArgument_ShouldThrowArgumentNull()\r
215         {\r
216             var part = CreatePart(typeof(MySharedPartExport));\r
217             var import = part.ImportDefinitions.First();\r
218 \r
219             ExceptionAssert.ThrowsArgument<ArgumentNullException>("exports", () =>\r
220             {\r
221                 part.SetImport(import, (IEnumerable<Export>)null);\r
222             });\r
223         }\r
224 \r
225         [TestMethod]\r
226         public void SetImport_ExportsArrayWithNullElementAsExportsArgument_ShouldThrowArgument()\r
227         {\r
228             var part = CreatePart(typeof(MySharedPartExport));\r
229             var definition = part.ImportDefinitions.First();\r
230 \r
231             ExceptionAssert.ThrowsArgument<ArgumentException>("exports", () =>\r
232             {\r
233                 part.SetImport(definition, new Export[] { null });\r
234             });\r
235         }\r
236 \r
237         [TestMethod]\r
238         public void SetImport_WrongDefinitionAsDefinitionArgument_ShouldThrowArgument()\r
239         {\r
240             var part = CreateDefaultPart();\r
241 \r
242             var definition = ImportDefinitionFactory.Create();\r
243 \r
244             ExceptionAssert.ThrowsArgument<ArgumentException>("definition", () =>\r
245             {\r
246                 part.SetImport(definition, Enumerable.Empty<Export>());\r
247             });\r
248         }\r
249 \r
250         [TestMethod]\r
251         public void SetImport_SetNonRecomposableDefinitionAsDefinitionArgumentAfterOnComposed_ShouldThrowInvalidOperation()\r
252         {\r
253             var part = CreatePartWithNonRecomposableImport();\r
254             var definition = part.ImportDefinitions.First();\r
255 \r
256             part.SetImport(definition, Enumerable.Empty<Export>());\r
257             part.Activate();\r
258 \r
259             ExceptionAssert.Throws<InvalidOperationException>(() =>\r
260             {\r
261                 part.SetImport(definition, Enumerable.Empty<Export>());\r
262             });\r
263         }\r
264 \r
265         [TestMethod]\r
266         public void SetImport_ZeroOrOneDefinitionAsDefinitionArgumentAndTwoExportsAsExportsArgument_ShouldThrowArgument()\r
267         {\r
268             var part = CreatePartWithZeroOrOneImport();\r
269             var definition = part.ImportDefinitions.First();\r
270 \r
271             var exports = ExportFactory.Create("Import", 2);\r
272 \r
273             ExceptionAssert.ThrowsArgument<ArgumentException>("exports", () =>\r
274             {\r
275                 part.SetImport(definition, exports);\r
276             });\r
277         }\r
278 \r
279         [TestMethod]\r
280         public void SetImport_ExactlyOneDefinitionAsDefinitionArgumentAndTwoExportsAsExportsArgument_ShouldThrowArgument()\r
281         {\r
282             var part = CreatePartWithExactlyOneImport();\r
283             var definition = part.ImportDefinitions.First();\r
284 \r
285             var exports = ExportFactory.Create("Import", 2);\r
286 \r
287             ExceptionAssert.ThrowsArgument<ArgumentException>("exports", () =>\r
288             {\r
289                 part.SetImport(definition, exports);\r
290             });\r
291         }\r
292 \r
293         [TestMethod]\r
294         public void SetImport_ExactlyOneDefinitionAsDefinitionArgumentAndEmptyExportsAsExportsArgument_ShouldThrowArgument()\r
295         {\r
296             var part = CreatePartWithExactlyOneImport();\r
297             var definition = part.ImportDefinitions.First();\r
298 \r
299             var exports = Enumerable.Empty<Export>();\r
300 \r
301             ExceptionAssert.ThrowsArgument<ArgumentException>("exports", () =>\r
302             {\r
303                 part.SetImport(definition, exports);\r
304             });\r
305         }\r
306 \r
307         [TestMethod]\r
308         public void SetImport_WrongTypeExportGiven_ShouldThrowComposablePart()\r
309         {\r
310             var part = CreatePart(new MySharedPartExport());\r
311             var import = part.ImportDefinitions.First();\r
312 \r
313             CompositionAssert.ThrowsPart(ErrorId.ReflectionModel_ImportNotAssignableFromExport, () =>\r
314             {\r
315                 part.SetImport(import, CreateSimpleExports("21"));\r
316             });\r
317         }\r
318 \r
319         [TestMethod]\r
320         public void SetImport_SetPostValueAndSetAgainOnInstance_ShouldSetProperty()\r
321         {\r
322             var import = new MySharedPartExport();\r
323             var part = CreatePart(import);\r
324             var importDef = part.ImportDefinitions.First();\r
325 \r
326             part.SetImport(importDef, CreateSimpleExports(21));\r
327 \r
328             Assert.AreNotEqual(import.Value, 21, "Value should NOT be set on live object until OnComposed");\r
329             part.Activate();\r
330 \r
331             Assert.AreEqual(import.Value, 21, "Value should be set on live object now");\r
332 \r
333             part.SetImport(importDef, CreateSimpleExports(42));\r
334 \r
335             Assert.AreNotEqual(import.Value, 42, "Value should NOT be rebound on live object");\r
336 \r
337             part.Activate();\r
338 \r
339             Assert.AreEqual(import.Value, 42, "Value should be set on live object now");\r
340         }\r
341 \r
342         [TestMethod]\r
343         public void GetExportedValue_WhenDisposed_ShouldThrowObjectDisposed()\r
344         {\r
345             var part = CreateDefaultDisposablePart();\r
346             var definition = part.ExportDefinitions.First();\r
347 \r
348             ((IDisposable)part).Dispose();\r
349 \r
350             ExceptionAssert.ThrowsDisposed(part, () =>\r
351             {\r
352                 part.GetExportedValue(definition);\r
353             });\r
354         }\r
355 \r
356         [TestMethod]\r
357         public void GetExportedValue_NullAsDefinitionArgument_ShouldThrowArgumentNull()\r
358         {\r
359             var part = CreateDefaultPart();\r
360 \r
361             ExceptionAssert.ThrowsArgument<ArgumentNullException>("definition", () =>\r
362             {\r
363                 part.GetExportedValue((ExportDefinition)null);\r
364             });\r
365         }\r
366 \r
367         [TestMethod]\r
368         public void GetExportedValue_WrongDefinitionAsDefinitionArgument_ShouldThrowArgument()\r
369         {\r
370             var part = CreateDefaultPart();\r
371             var definition = ExportDefinitionFactory.Create();\r
372 \r
373             ExceptionAssert.ThrowsArgument<ArgumentException>("definition", () =>\r
374             {\r
375                 part.GetExportedValue(definition);\r
376             });\r
377         }\r
378 \r
379         [TestMethod]\r
380         public void GetExportedValue_MissingPrerequisiteImport_ShouldThrowInvalidOperation()\r
381         {\r
382             var part = CreatePart(typeof(SimpleConstructorInjectedObject));\r
383             var definition = part.ExportDefinitions.First();\r
384 \r
385             ExceptionAssert.Throws<InvalidOperationException>(() =>\r
386             {\r
387                 part.GetExportedValue(definition);\r
388             });\r
389         }\r
390 \r
391         [Ignore]\r
392         [TestMethod]\r
393         [WorkItem(484204)]\r
394         public void GetExportedValue_MissingPostImports_ShouldThrowComposition()\r
395         {\r
396             var part = CreatePart(typeof(MySharedPartExport));\r
397 \r
398             // Signal that the composition should be finished\r
399             part.Activate();\r
400 \r
401             var definition = part.ExportDefinitions.First();\r
402 \r
403             // Dev10:484204 - This used to cause a failure but after we made \r
404             // ReflectionComposablePart internal we needed to back remove this \r
405             // validation for post imports to make declarative composition work.\r
406             CompositionAssert.ThrowsError(ErrorId.ImportNotSetOnPart, () =>\r
407             {\r
408                 part.GetExportedValue(definition);\r
409             });\r
410         }\r
411 \r
412         [TestMethod]\r
413         public void GetExportedValue_NoConstructorOnDefinition_ShouldThrowComposablePart()\r
414         {\r
415             var part = CreatePart(typeof(ClassWithNoMarkedOrDefaultConstructor));\r
416 \r
417             var definition = part.ExportDefinitions.First();\r
418 \r
419             CompositionAssert.ThrowsPart(ErrorId.ReflectionModel_PartConstructorMissing, () =>\r
420             {\r
421                 part.GetExportedValue(definition);\r
422             });\r
423         }\r
424 \r
425         [TestMethod]\r
426         public void GetExportedValue_UnhandledExceptionThrowInConstructor_ShouldThrowComposablePart()\r
427         {\r
428             var part = CreatePart(typeof(ExportWithExceptionDuringConstruction));\r
429 \r
430             var definition = part.ExportDefinitions.First();\r
431 \r
432             CompositionAssert.ThrowsPart<NotImplementedException>(ErrorId.ReflectionModel_PartConstructorThrewException, () =>\r
433             {\r
434                 part.GetExportedValue(definition);\r
435             });\r
436         }\r
437 \r
438         [TestMethod]\r
439         public void GetExportedValue_GetObjectAfterSetPreImport_ShouldGetValue()\r
440         {\r
441             var part = CreatePart(typeof(SimpleConstructorInjectedObject));\r
442 \r
443             var import = part.ImportDefinitions.First();\r
444             part.SetImport(import, CreateSimpleExports(21));\r
445 \r
446             part.Activate();\r
447 \r
448             var definition = part.ExportDefinitions.First();\r
449             var exportObject = (SimpleConstructorInjectedObject)part.GetExportedValue(definition);\r
450 \r
451             Assert.AreEqual(21, exportObject.CISimpleValue);\r
452         }\r
453 \r
454         [TestMethod]\r
455         public void GetExportedValue_GetObjectAfterSetPostImport_ShouldGetValue()\r
456         {\r
457             var part = CreatePart(typeof(MySharedPartExport));\r
458 \r
459             var import = part.ImportDefinitions.First();\r
460             part.SetImport(import, CreateSimpleExports(21));\r
461 \r
462             part.Activate();\r
463 \r
464             var definition = part.ExportDefinitions.First();\r
465             var exportObject = (MySharedPartExport)part.GetExportedValue(definition);\r
466 \r
467             Assert.IsNotNull(exportObject);\r
468             Assert.AreEqual(21, exportObject.Value);\r
469         }\r
470 \r
471         [TestMethod]\r
472         public void GetExportedValue_CallMultipleTimes_ShouldReturnSame()\r
473         {\r
474             var part = CreatePart(typeof(MySharedPartExport));\r
475 \r
476             var import = part.ImportDefinitions.First();\r
477             part.SetImport(import, CreateSimpleExports(21));\r
478 \r
479             part.Activate();\r
480 \r
481             var definition = part.ExportDefinitions.First();\r
482             var exportedValue1 = part.GetExportedValue(definition);\r
483             var exportedValue2 = part.GetExportedValue(definition);\r
484 \r
485             Assert.AreSame(exportedValue1, exportedValue2);\r
486         }\r
487 \r
488         [TestMethod]\r
489         public void GetExportedValue_FromStaticClass_ShouldReturnExport()\r
490         {\r
491             var part = CreatePart(typeof(StaticExportClass));\r
492 \r
493             var definition = part.ExportDefinitions.First();\r
494 \r
495             var exportObject = (string)part.GetExportedValue(definition);\r
496 \r
497             Assert.AreEqual("StaticString", exportObject);\r
498         }\r
499 \r
500         [TestMethod]\r
501         public void GetExportedValue_OptionalPostNotGiven_ShouldReturnValidObject()\r
502         {\r
503             var part = CreatePart(typeof(ClassWithOptionalPostImport));\r
504             part.Activate();\r
505 \r
506             var definition = part.ExportDefinitions.First();\r
507             var exportObject = (ClassWithOptionalPostImport)part.GetExportedValue(definition);\r
508 \r
509             Assert.IsNull(exportObject.Formatter);\r
510         }\r
511 \r
512         [TestMethod]\r
513         public void GetExportedValue_OptionalPreNotGiven_ShouldReturnValidObject()\r
514         {\r
515             var part = CreatePart(typeof(ClassWithOptionalPreImport));\r
516             part.Activate();\r
517 \r
518             var definition = part.ExportDefinitions.First();\r
519 \r
520             var exportedValue = (ClassWithOptionalPreImport)part.GetExportedValue(definition);\r
521             Assert.IsNull(exportedValue.Formatter);\r
522         }\r
523 \r
524         [TestMethod]\r
525         public void ICompositionElementDisplayName_ShouldReturnTypeDisplayName()\r
526         {\r
527             var expectations = Expectations.GetAttributedTypes();\r
528             foreach (var e in expectations)\r
529             {\r
530                 var part = (ICompositionElement)CreatePart(e);\r
531 \r
532                 Assert.AreEqual(e.GetDisplayName(), part.DisplayName);\r
533             }\r
534         }\r
535 \r
536         [TestMethod]\r
537         public void ToString_ShouldReturnICompositionElementDisplayName()\r
538         {\r
539             var expectations = Expectations.GetAttributedTypes();\r
540             foreach (var e in expectations)\r
541             {\r
542                 var part = (ICompositionElement)CreatePart(e);\r
543 \r
544                 Assert.AreEqual(part.DisplayName, part.ToString());\r
545             }\r
546         }\r
547 \r
548         [PartNotDiscoverable]\r
549         public class PropertyExporter\r
550         {\r
551             [Export]\r
552             public object Property { get { return new object(); } }\r
553         }\r
554 \r
555         [PartNotDiscoverable]\r
556         public class FieldExporter\r
557         {\r
558             [Export]\r
559             public object Field = null;\r
560         }\r
561 \r
562         [PartNotDiscoverable]\r
563         public class MethodExporter\r
564         {\r
565             [Export("Method")]\r
566             public void Method() { }\r
567         }\r
568 \r
569         [PartNotDiscoverable]\r
570         [Export]\r
571         public class TypeExporter\r
572         {\r
573         }\r
574 \r
575         [TestMethod]\r
576         public void GetExportedObjectAlwaysReturnsSameReference_ForProperty()\r
577         {\r
578             var cp = CreatePart(new PropertyExporter());\r
579             var ed = cp.ExportDefinitions.Single();\r
580             var eo1 = cp.GetExportedValue(ed);\r
581             var eo2 = cp.GetExportedValue(ed);\r
582             Assert.AreSame(eo1, eo2);\r
583         }\r
584 \r
585         [TestMethod]\r
586         public void GetExportedObjectAlwaysReturnsSameReference_ForField()\r
587         {\r
588             var exporter = new FieldExporter();\r
589             var cp = CreatePart(new FieldExporter());\r
590             var ed = cp.ExportDefinitions.Single();\r
591 \r
592             exporter.Field = new object();\r
593             var eo1 = cp.GetExportedValue(ed);\r
594             exporter.Field = new object();\r
595             var eo2 = cp.GetExportedValue(ed);\r
596             Assert.AreSame(eo1, eo2);\r
597         }\r
598 \r
599         [TestMethod]\r
600         public void GetExportedObjectAlwaysReturnsSameReference_ForMethod()\r
601         {\r
602             var cp = CreatePart(new MethodExporter());\r
603             var ed = cp.ExportDefinitions.Single();\r
604             var eo1 = cp.GetExportedValue(ed);\r
605             var eo2 = cp.GetExportedValue(ed);\r
606             Assert.AreSame(eo1, eo2);\r
607         }\r
608 \r
609         [TestMethod]\r
610         public void GetExportedObjectAlwaysReturnsSameReference_ForType()\r
611         {\r
612             var cp = CreatePart(new TypeExporter());\r
613             var ed = cp.ExportDefinitions.Single();\r
614             var eo1 = cp.GetExportedValue(ed);\r
615             var eo2 = cp.GetExportedValue(ed);\r
616             Assert.AreSame(eo1, eo2);\r
617         }\r
618 \r
619 \r
620         [PartNotDiscoverable]\r
621         public class MethodWithoutContractName\r
622         {\r
623             [Export]\r
624             public void MethodWithoutContractNameNotAllowed()\r
625             {\r
626             }\r
627         }\r
628 \r
629         public interface IContract\r
630         {\r
631         }\r
632 \r
633 \r
634         [AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = false)]\r
635         public class CustomImportAttributeInvalidTarget : ImportAttribute\r
636         {\r
637             public CustomImportAttributeInvalidTarget()\r
638                 : base(typeof(IContract))\r
639             {\r
640             }\r
641         }\r
642 \r
643         [PartNotDiscoverable]\r
644         public class ImportWithCustomImport\r
645         {\r
646             [CustomImport]\r
647             IContract ImportWithCustomAttributeImport { get; set; }\r
648         }\r
649 \r
650         [PartNotDiscoverable]\r
651         public class ImportWithCustomImportInvalidTarget\r
652         {\r
653             [CustomImportAttributeInvalidTarget]\r
654             void InvalidImport() { }\r
655         }\r
656 \r
657         [TestMethod]\r
658         public void ImportDefinitions_ImportWithCustomAttributeImports()\r
659         {\r
660             var part = CreatePart(typeof(ImportWithCustomImport));\r
661             Assert.AreEqual(part.ImportDefinitions.Count(), 1);\r
662             ContractBasedImportDefinition import = part.ImportDefinitions.First() as ContractBasedImportDefinition;\r
663             Assert.IsNotNull(import);\r
664 \r
665             Assert.AreEqual(AttributedModelServices.GetContractName(typeof(IContract)), import.ContractName);\r
666             Assert.AreEqual(AttributedModelServices.GetTypeIdentity(typeof(IContract)), import.RequiredTypeIdentity);\r
667         }\r
668 \r
669         [TestMethod]\r
670         public void ImportDefinitions_ImportWithCustomImportInvalidTarget_ShouldbeIgnored()\r
671         {\r
672             var part = CreatePart(typeof(ImportWithCustomImportInvalidTarget));\r
673             Assert.AreEqual(part.ImportDefinitions.Count(), 0);\r
674         }        \r
675 \r
676         [PartNotDiscoverable]\r
677         public class ImportManyWithCustomImportMany\r
678         {\r
679             [CustomImportMany]\r
680             IContract ImportManyWithCustomAttributeImportMany { get; set; }\r
681         }\r
682 \r
683         [PartNotDiscoverable]\r
684         public class ImportManyWithCustomImportManyInvalidTarget\r
685         {\r
686             [CustomImportMany]\r
687             void InvalidImportMany() { }\r
688         }\r
689 \r
690         [TestMethod]\r
691         public void ImportDefinitions_ImportManyWithCustomAttributeImportManys()\r
692         {\r
693             var part = CreatePart(typeof(ImportManyWithCustomImportMany));\r
694             Assert.AreEqual(part.ImportDefinitions.Count(), 1);\r
695             ContractBasedImportDefinition import = part.ImportDefinitions.First() as ContractBasedImportDefinition;\r
696             Assert.IsNotNull(import);\r
697 \r
698             Assert.AreEqual(AttributedModelServices.GetContractName(typeof(IContract)), import.ContractName);\r
699             Assert.AreEqual(AttributedModelServices.GetTypeIdentity(typeof(IContract)), import.RequiredTypeIdentity);\r
700         }\r
701 \r
702         [TestMethod]\r
703         public void ImportDefinitions_ImportManyWithCustomImportManyInvalidTarget_ShouldbeIgnored()\r
704         {\r
705             var part = CreatePart(typeof(ImportManyWithCustomImportManyInvalidTarget));\r
706             Assert.AreEqual(part.ImportDefinitions.Count(), 0);\r
707         }\r
708 \r
709         [AttributeUsage(AttributeTargets.Constructor, AllowMultiple = false, Inherited = false)]\r
710         public class CustomImportingConstructorAttribute : ImportingConstructorAttribute\r
711         {\r
712             public CustomImportingConstructorAttribute()\r
713                 : base()\r
714             {\r
715             }\r
716         }\r
717 \r
718         [AttributeUsage(AttributeTargets.Constructor, AllowMultiple = true, Inherited = false)]\r
719         public class CustomImportingConstructorAllowMultipleAttribute : ImportingConstructorAttribute\r
720         {\r
721             public CustomImportingConstructorAllowMultipleAttribute()\r
722                 : base()\r
723             {\r
724             }\r
725         }\r
726 \r
727         [AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = false)]\r
728         public class CustomImportingConstructorInvalidTargetAttribute : ImportingConstructorAttribute\r
729         {\r
730             public CustomImportingConstructorInvalidTargetAttribute()\r
731                 : base()\r
732             {\r
733             }\r
734         }\r
735 \r
736         [PartNotDiscoverable]\r
737         public class ImportingConstructorWithCustomImportingConstructor\r
738         {\r
739             [CustomImportingConstructor]\r
740             ImportingConstructorWithCustomImportingConstructor([Import] IContract argument) {}\r
741         }\r
742 \r
743         [PartNotDiscoverable]\r
744         public class ImportingConstructorWithCustomImportingConstructorAllowMultiple\r
745         {\r
746             [CustomImportingConstructorAllowMultiple]\r
747             [CustomImportingConstructorAllowMultiple]\r
748             ImportingConstructorWithCustomImportingConstructorAllowMultiple([Import] IContract argument) { }\r
749         }\r
750 \r
751         [PartNotDiscoverable]\r
752         public class ImportingConstructorWithCustomImportingConstructorInvalidTarget\r
753         {\r
754             [CustomImportingConstructorInvalidTarget]\r
755             void InvalidImportingConstructor() { }\r
756         }\r
757 \r
758         [TestMethod]\r
759         public void ImportDefinitions_ImportingConstructorWithCustomAttributeImportingConstructors()\r
760         {\r
761             var part = CreatePart(typeof(ImportingConstructorWithCustomImportingConstructor));\r
762             Assert.AreEqual(part.ImportDefinitions.Count(), 1);\r
763             ContractBasedImportDefinition import = part.ImportDefinitions.First() as ContractBasedImportDefinition;\r
764             Assert.IsNotNull(import);\r
765 \r
766             Assert.AreEqual(AttributedModelServices.GetContractName(typeof(IContract)), import.ContractName);\r
767             Assert.AreEqual(AttributedModelServices.GetTypeIdentity(typeof(IContract)), import.RequiredTypeIdentity);\r
768         }\r
769 \r
770         [TestMethod]\r
771         public void ImportDefinitions_ImportingConstructorWithCustomAttributeImportingConstructorsWithAllowMultiple_ShouldNotThrowInvalidOperation()\r
772         {\r
773             var part = CreatePart(typeof(ImportingConstructorWithCustomImportingConstructorAllowMultiple));\r
774 \r
775             Assert.AreEqual(part.ImportDefinitions.Count(), 1);\r
776             ContractBasedImportDefinition import = part.ImportDefinitions.First() as ContractBasedImportDefinition;\r
777             Assert.IsNotNull(import);\r
778 \r
779             Assert.AreEqual(AttributedModelServices.GetContractName(typeof(IContract)), import.ContractName);\r
780             Assert.AreEqual(AttributedModelServices.GetTypeIdentity(typeof(IContract)), import.RequiredTypeIdentity);\r
781         }\r
782 \r
783         [TestMethod]\r
784         public void ImportDefinitions_ImportingConstructorWithCustomImportingConstructorInvalidTarget_ShouldbeIgnored()\r
785         {\r
786             var part = CreatePart(typeof(ImportingConstructorWithCustomImportingConstructorInvalidTarget));\r
787             Assert.AreEqual(part.ImportDefinitions.Count(), 0);\r
788         }\r
789 #if !SILVERLIGHT\r
790 \r
791         [Export]\r
792         public class ClassWithMultipleParameterImports\r
793         {\r
794             [ImportingConstructor]\r
795             public ClassWithMultipleParameterImports([Import][ImportMany]string parameter)\r
796             {\r
797             }\r
798         }\r
799 \r
800         [Export]\r
801         public class ClassWithMultipleFieldImports\r
802         {\r
803             [Import]\r
804             [ImportMany]\r
805             public string Field;\r
806         }\r
807 \r
808         [Export]\r
809         public class ClassWithMultiplePropertyImports\r
810         {\r
811             [Import]\r
812             [ImportMany]\r
813             public string Property\r
814             {\r
815                 get;\r
816                 set;\r
817             }\r
818         }\r
819 \r
820         [Export]\r
821         public class ClassWithMultipleCustomPropertyImports\r
822         {\r
823             [CustomImport]\r
824             [CustomImport]\r
825             string Property { get; set; }\r
826         }\r
827 \r
828         [Export]\r
829         public class ClassWithMultipleCustomPropertyImportManys\r
830         {\r
831             [CustomImportMany]\r
832             [CustomImportMany]\r
833             string Property { get; set; }\r
834         }\r
835 \r
836         [Export]\r
837         public class ClassWithMultipleCustomPropertyImportAndImportManys\r
838         {\r
839             [CustomImport]\r
840             [CustomImportMany]\r
841             string Property { get; set; }\r
842         }\r
843 \r
844         [TestMethod]\r
845         public void ImportDefinitions_TypeWithMemberMarkedWithMultipleImports_ShouldTraceError()\r
846         {\r
847             var types = new Type[] { typeof(ClassWithMultipleParameterImports),\r
848                                      typeof(ClassWithMultipleFieldImports),\r
849                                      typeof(ClassWithMultiplePropertyImports),\r
850                                      typeof(ClassWithMultipleCustomPropertyImports),\r
851                                      typeof(ClassWithMultipleCustomPropertyImportManys),\r
852                                      typeof(ClassWithMultipleCustomPropertyImportAndImportManys)};\r
853 \r
854             foreach (Type type in types)\r
855             {\r
856                 using (TraceContext context = new TraceContext(SourceLevels.Error))\r
857                 {\r
858                     var definition = AttributedModelServices.CreatePartDefinition(type, null, true);\r
859                     definition.ImportDefinitions.Count();\r
860 \r
861                     Assert.IsNotNull(context.LastTraceEvent);\r
862                     Assert.AreEqual(context.LastTraceEvent.EventType, TraceEventType.Error);\r
863                     Assert.AreEqual(context.LastTraceEvent.Id, TraceId.Discovery_MemberMarkedWithMultipleImportAndImportMany);\r
864                 }\r
865             }\r
866         }\r
867 #endif\r
868 \r
869         private Export[] CreateSimpleExports(object value)\r
870         {\r
871             var export = ExportFactory.Create("NoContract", () => value);\r
872 \r
873             return new Export[] { export };\r
874         }\r
875 \r
876         private ReflectionComposablePart CreatePartWithExport()\r
877         {\r
878             return CreatePart(typeof(StaticExportClass));\r
879         }\r
880 \r
881         private ReflectionComposablePart CreatePartWithNonRecomposableImport()\r
882         {\r
883             return CreatePart(typeof(SingleImportWithAllowDefault));\r
884         }\r
885 \r
886         private ReflectionComposablePart CreatePartWithZeroOrOneImport()\r
887         {\r
888             return CreatePart(typeof(SingleImportWithAllowDefault));\r
889         }\r
890 \r
891         private ReflectionComposablePart CreatePartWithExactlyOneImport()\r
892         {\r
893             return CreatePart(typeof(SingleImport));\r
894         }\r
895 \r
896         private ReflectionComposablePart CreateDefaultPart()\r
897         {\r
898             return CreatePart(new object());\r
899         }\r
900 \r
901         [PartNotDiscoverable]\r
902         [Export]\r
903         public class DisposablePart : IDisposable\r
904         {\r
905             [Import(AllowDefault = true)]\r
906             public int Foo { get; set; }\r
907 \r
908             public void Dispose() { }\r
909         }\r
910 \r
911         private ReflectionComposablePart CreateDefaultDisposablePart()\r
912         {\r
913             return CreatePart(typeof(DisposablePart));\r
914         }\r
915 \r
916         private ReflectionComposablePart CreatePart(object instance)\r
917         {\r
918             if (instance is Type)\r
919             {\r
920                 var definition = PartDefinitionFactory.CreateAttributed((Type)instance);\r
921 \r
922                 return (ReflectionComposablePart)definition.CreatePart();\r
923             }\r
924             else\r
925             {\r
926                 var definition = PartDefinitionFactory.CreateAttributed(instance.GetType()); \r
927 \r
928                 return new ReflectionComposablePart(definition, instance);\r
929             }\r
930         }\r
931     }\r
932 }\r