1 // -----------------------------------------------------------------------
\r
2 // Copyright (c) Microsoft Corporation. All rights reserved.
\r
3 // -----------------------------------------------------------------------
\r
5 using System.ComponentModel.Composition;
\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
20 namespace System.ComponentModel.Composition.ReflectionModel
\r
23 public class ReflectionComposablePartTests
\r
26 public void Constructor1_DefinitionAsDefinitionArgument_ShouldSetOriginProperty()
\r
28 var expectations = Expectations.GetAttributedDefinitions();
\r
30 foreach (var e in expectations)
\r
32 var definition = (ICompositionElement)new ReflectionComposablePart(e);
\r
34 Assert.AreSame(e, definition.Origin);
\r
39 public void Constructor1_NullAsDefinitionArgument_ShouldThrowArgumentNull()
\r
41 ExceptionAssert.ThrowsArgument<ArgumentNullException>("definition", () =>
\r
43 new ReflectionComposablePart((ReflectionComposablePartDefinition)null);
\r
48 public void Constructor2_NullAsAttributedPartArgument_ShouldThrowArgumentNull()
\r
50 ExceptionAssert.ThrowsArgument<ArgumentNullException>("attributedPart", () =>
\r
52 new ReflectionComposablePart(PartDefinitionFactory.CreateAttributed(), (object)null);
\r
57 public void Constructor2_ValueTypeAsAttributedPartArgument_ShouldThrowArgument()
\r
59 ExceptionAssert.ThrowsArgument<ArgumentException>("attributedPart", () =>
\r
61 new ReflectionComposablePart(PartDefinitionFactory.CreateAttributed(), 42);
\r
67 public void Constructor1_AttributedComposablePartDefintion_ShouldProduceValidObject()
\r
69 var definition = PartDefinitionFactory.CreateAttributed(typeof(MyExport));
\r
70 var part = new ReflectionComposablePart(definition);
\r
72 Assert.AreEqual(definition, part.Definition);
\r
73 Assert.IsNotNull(part.Metadata);
\r
75 Assert.IsFalse(part is IDisposable);
\r
79 public void Constructor1_AttributedComposablePartDefintion_Disposable_ShouldProduceValidObject()
\r
81 var definition = PartDefinitionFactory.CreateAttributed(typeof(DisposablePart));
\r
82 var part = new DisposableReflectionComposablePart(definition);
\r
84 Assert.AreEqual(definition, part.Definition);
\r
85 Assert.IsNotNull(part.Metadata);
\r
87 Assert.IsTrue(part is IDisposable);
\r
91 public void Constructor1_Type_ShouldProduceValidObject()
\r
93 var part = new ReflectionComposablePart(PartDefinitionFactory.CreateAttributed(typeof(MyExport)));
\r
97 public void Constructor1_Object_ShouldProduceValidObject()
\r
99 var part = new ReflectionComposablePart(PartDefinitionFactory.CreateAttributed(typeof(MyExport)), new MyExport());
\r
103 public void Metadata_WhenDisposed_ShouldThrowObjectDisposed()
\r
105 var part = CreateDefaultDisposablePart();
\r
106 ((IDisposable)part).Dispose();
\r
108 ExceptionAssert.ThrowsDisposed(part, () =>
\r
110 var metadata = part.Metadata;
\r
115 public void ImportDefinitions_WhenDisposed_ShouldThrowObjectDisposed()
\r
117 var part = CreateDefaultDisposablePart();
\r
118 ((IDisposable)part).Dispose();
\r
120 ExceptionAssert.ThrowsDisposed(part, () =>
\r
122 var definitions = part.ImportDefinitions;
\r
127 public void ExportDefinitions_WhenDisposed_ShouldThrowObjectDisposed()
\r
129 var part = CreateDefaultDisposablePart();
\r
130 ((IDisposable)part).Dispose();
\r
132 ExceptionAssert.ThrowsDisposed(part, () =>
\r
134 var definitions = part.ExportDefinitions;
\r
138 public void OnComposed_WhenDisposed_ShouldThrowObjectDisposed()
\r
140 var part = CreateDefaultDisposablePart();
\r
141 ((IDisposable)part).Dispose();
\r
143 ExceptionAssert.ThrowsDisposed(part, () =>
\r
150 public void OnComposed_MissingPostImportsOnInstance_ShouldThrowComposition()
\r
152 var part = CreatePart(new MySharedPartExport());
\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
162 public void OnComposed_ProperlyComposed_ShouldSucceed()
\r
164 var import = new TrivialImporter();
\r
165 var export = new TrivialExporter();
\r
167 var part = CreatePart(import);
\r
169 var importDef = part.ImportDefinitions.First();
\r
170 part.SetImport(importDef, CreateSimpleExports(export));
\r
172 Assert.IsTrue(export.done, "OnImportsSatisfied should have been called");
\r
176 public void OnComposed_UnhandledExceptionThrowInOnImportsSatisfied_ShouldThrowComposablePart()
\r
178 var part = CreatePart(typeof(ExceptionDuringINotifyImport));
\r
179 var definition = part.ImportDefinitions.First();
\r
180 part.SetImport(definition, CreateSimpleExports(21));
\r
182 CompositionAssert.ThrowsPart<NotImplementedException>(ErrorId.ReflectionModel_PartOnImportsSatisfiedThrewException, RetryMode.DoNotRetry, () =>
\r
189 public void SetImport_WhenDisposed_ShouldThrowObjectDisposed()
\r
191 var part = CreateDefaultDisposablePart();
\r
192 var definition = part.ImportDefinitions.First();
\r
194 ((IDisposable)part).Dispose();
\r
196 ExceptionAssert.ThrowsDisposed(part, () =>
\r
198 part.SetImport(definition, Enumerable.Empty<Export>());
\r
203 public void SetImport_NullAsImportDefinitionArgument_ShouldThrowArgumentNull()
\r
205 var part = CreateDefaultPart();
\r
207 ExceptionAssert.ThrowsArgument<ArgumentNullException>("definition", () =>
\r
209 part.SetImport((ImportDefinition)null, Enumerable.Empty<Export>());
\r
214 public void SetImport_NullAsExportsArgument_ShouldThrowArgumentNull()
\r
216 var part = CreatePart(typeof(MySharedPartExport));
\r
217 var import = part.ImportDefinitions.First();
\r
219 ExceptionAssert.ThrowsArgument<ArgumentNullException>("exports", () =>
\r
221 part.SetImport(import, (IEnumerable<Export>)null);
\r
226 public void SetImport_ExportsArrayWithNullElementAsExportsArgument_ShouldThrowArgument()
\r
228 var part = CreatePart(typeof(MySharedPartExport));
\r
229 var definition = part.ImportDefinitions.First();
\r
231 ExceptionAssert.ThrowsArgument<ArgumentException>("exports", () =>
\r
233 part.SetImport(definition, new Export[] { null });
\r
238 public void SetImport_WrongDefinitionAsDefinitionArgument_ShouldThrowArgument()
\r
240 var part = CreateDefaultPart();
\r
242 var definition = ImportDefinitionFactory.Create();
\r
244 ExceptionAssert.ThrowsArgument<ArgumentException>("definition", () =>
\r
246 part.SetImport(definition, Enumerable.Empty<Export>());
\r
251 public void SetImport_SetNonRecomposableDefinitionAsDefinitionArgumentAfterOnComposed_ShouldThrowInvalidOperation()
\r
253 var part = CreatePartWithNonRecomposableImport();
\r
254 var definition = part.ImportDefinitions.First();
\r
256 part.SetImport(definition, Enumerable.Empty<Export>());
\r
259 ExceptionAssert.Throws<InvalidOperationException>(() =>
\r
261 part.SetImport(definition, Enumerable.Empty<Export>());
\r
266 public void SetImport_ZeroOrOneDefinitionAsDefinitionArgumentAndTwoExportsAsExportsArgument_ShouldThrowArgument()
\r
268 var part = CreatePartWithZeroOrOneImport();
\r
269 var definition = part.ImportDefinitions.First();
\r
271 var exports = ExportFactory.Create("Import", 2);
\r
273 ExceptionAssert.ThrowsArgument<ArgumentException>("exports", () =>
\r
275 part.SetImport(definition, exports);
\r
280 public void SetImport_ExactlyOneDefinitionAsDefinitionArgumentAndTwoExportsAsExportsArgument_ShouldThrowArgument()
\r
282 var part = CreatePartWithExactlyOneImport();
\r
283 var definition = part.ImportDefinitions.First();
\r
285 var exports = ExportFactory.Create("Import", 2);
\r
287 ExceptionAssert.ThrowsArgument<ArgumentException>("exports", () =>
\r
289 part.SetImport(definition, exports);
\r
294 public void SetImport_ExactlyOneDefinitionAsDefinitionArgumentAndEmptyExportsAsExportsArgument_ShouldThrowArgument()
\r
296 var part = CreatePartWithExactlyOneImport();
\r
297 var definition = part.ImportDefinitions.First();
\r
299 var exports = Enumerable.Empty<Export>();
\r
301 ExceptionAssert.ThrowsArgument<ArgumentException>("exports", () =>
\r
303 part.SetImport(definition, exports);
\r
308 public void SetImport_WrongTypeExportGiven_ShouldThrowComposablePart()
\r
310 var part = CreatePart(new MySharedPartExport());
\r
311 var import = part.ImportDefinitions.First();
\r
313 CompositionAssert.ThrowsPart(ErrorId.ReflectionModel_ImportNotAssignableFromExport, () =>
\r
315 part.SetImport(import, CreateSimpleExports("21"));
\r
320 public void SetImport_SetPostValueAndSetAgainOnInstance_ShouldSetProperty()
\r
322 var import = new MySharedPartExport();
\r
323 var part = CreatePart(import);
\r
324 var importDef = part.ImportDefinitions.First();
\r
326 part.SetImport(importDef, CreateSimpleExports(21));
\r
328 Assert.AreNotEqual(import.Value, 21, "Value should NOT be set on live object until OnComposed");
\r
331 Assert.AreEqual(import.Value, 21, "Value should be set on live object now");
\r
333 part.SetImport(importDef, CreateSimpleExports(42));
\r
335 Assert.AreNotEqual(import.Value, 42, "Value should NOT be rebound on live object");
\r
339 Assert.AreEqual(import.Value, 42, "Value should be set on live object now");
\r
343 public void GetExportedValue_WhenDisposed_ShouldThrowObjectDisposed()
\r
345 var part = CreateDefaultDisposablePart();
\r
346 var definition = part.ExportDefinitions.First();
\r
348 ((IDisposable)part).Dispose();
\r
350 ExceptionAssert.ThrowsDisposed(part, () =>
\r
352 part.GetExportedValue(definition);
\r
357 public void GetExportedValue_NullAsDefinitionArgument_ShouldThrowArgumentNull()
\r
359 var part = CreateDefaultPart();
\r
361 ExceptionAssert.ThrowsArgument<ArgumentNullException>("definition", () =>
\r
363 part.GetExportedValue((ExportDefinition)null);
\r
368 public void GetExportedValue_WrongDefinitionAsDefinitionArgument_ShouldThrowArgument()
\r
370 var part = CreateDefaultPart();
\r
371 var definition = ExportDefinitionFactory.Create();
\r
373 ExceptionAssert.ThrowsArgument<ArgumentException>("definition", () =>
\r
375 part.GetExportedValue(definition);
\r
380 public void GetExportedValue_MissingPrerequisiteImport_ShouldThrowInvalidOperation()
\r
382 var part = CreatePart(typeof(SimpleConstructorInjectedObject));
\r
383 var definition = part.ExportDefinitions.First();
\r
385 ExceptionAssert.Throws<InvalidOperationException>(() =>
\r
387 part.GetExportedValue(definition);
\r
394 public void GetExportedValue_MissingPostImports_ShouldThrowComposition()
\r
396 var part = CreatePart(typeof(MySharedPartExport));
\r
398 // Signal that the composition should be finished
\r
401 var definition = part.ExportDefinitions.First();
\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
408 part.GetExportedValue(definition);
\r
413 public void GetExportedValue_NoConstructorOnDefinition_ShouldThrowComposablePart()
\r
415 var part = CreatePart(typeof(ClassWithNoMarkedOrDefaultConstructor));
\r
417 var definition = part.ExportDefinitions.First();
\r
419 CompositionAssert.ThrowsPart(ErrorId.ReflectionModel_PartConstructorMissing, () =>
\r
421 part.GetExportedValue(definition);
\r
426 public void GetExportedValue_UnhandledExceptionThrowInConstructor_ShouldThrowComposablePart()
\r
428 var part = CreatePart(typeof(ExportWithExceptionDuringConstruction));
\r
430 var definition = part.ExportDefinitions.First();
\r
432 CompositionAssert.ThrowsPart<NotImplementedException>(ErrorId.ReflectionModel_PartConstructorThrewException, () =>
\r
434 part.GetExportedValue(definition);
\r
439 public void GetExportedValue_GetObjectAfterSetPreImport_ShouldGetValue()
\r
441 var part = CreatePart(typeof(SimpleConstructorInjectedObject));
\r
443 var import = part.ImportDefinitions.First();
\r
444 part.SetImport(import, CreateSimpleExports(21));
\r
448 var definition = part.ExportDefinitions.First();
\r
449 var exportObject = (SimpleConstructorInjectedObject)part.GetExportedValue(definition);
\r
451 Assert.AreEqual(21, exportObject.CISimpleValue);
\r
455 public void GetExportedValue_GetObjectAfterSetPostImport_ShouldGetValue()
\r
457 var part = CreatePart(typeof(MySharedPartExport));
\r
459 var import = part.ImportDefinitions.First();
\r
460 part.SetImport(import, CreateSimpleExports(21));
\r
464 var definition = part.ExportDefinitions.First();
\r
465 var exportObject = (MySharedPartExport)part.GetExportedValue(definition);
\r
467 Assert.IsNotNull(exportObject);
\r
468 Assert.AreEqual(21, exportObject.Value);
\r
472 public void GetExportedValue_CallMultipleTimes_ShouldReturnSame()
\r
474 var part = CreatePart(typeof(MySharedPartExport));
\r
476 var import = part.ImportDefinitions.First();
\r
477 part.SetImport(import, CreateSimpleExports(21));
\r
481 var definition = part.ExportDefinitions.First();
\r
482 var exportedValue1 = part.GetExportedValue(definition);
\r
483 var exportedValue2 = part.GetExportedValue(definition);
\r
485 Assert.AreSame(exportedValue1, exportedValue2);
\r
489 public void GetExportedValue_FromStaticClass_ShouldReturnExport()
\r
491 var part = CreatePart(typeof(StaticExportClass));
\r
493 var definition = part.ExportDefinitions.First();
\r
495 var exportObject = (string)part.GetExportedValue(definition);
\r
497 Assert.AreEqual("StaticString", exportObject);
\r
501 public void GetExportedValue_OptionalPostNotGiven_ShouldReturnValidObject()
\r
503 var part = CreatePart(typeof(ClassWithOptionalPostImport));
\r
506 var definition = part.ExportDefinitions.First();
\r
507 var exportObject = (ClassWithOptionalPostImport)part.GetExportedValue(definition);
\r
509 Assert.IsNull(exportObject.Formatter);
\r
513 public void GetExportedValue_OptionalPreNotGiven_ShouldReturnValidObject()
\r
515 var part = CreatePart(typeof(ClassWithOptionalPreImport));
\r
518 var definition = part.ExportDefinitions.First();
\r
520 var exportedValue = (ClassWithOptionalPreImport)part.GetExportedValue(definition);
\r
521 Assert.IsNull(exportedValue.Formatter);
\r
525 public void ICompositionElementDisplayName_ShouldReturnTypeDisplayName()
\r
527 var expectations = Expectations.GetAttributedTypes();
\r
528 foreach (var e in expectations)
\r
530 var part = (ICompositionElement)CreatePart(e);
\r
532 Assert.AreEqual(e.GetDisplayName(), part.DisplayName);
\r
537 public void ToString_ShouldReturnICompositionElementDisplayName()
\r
539 var expectations = Expectations.GetAttributedTypes();
\r
540 foreach (var e in expectations)
\r
542 var part = (ICompositionElement)CreatePart(e);
\r
544 Assert.AreEqual(part.DisplayName, part.ToString());
\r
548 [PartNotDiscoverable]
\r
549 public class PropertyExporter
\r
552 public object Property { get { return new object(); } }
\r
555 [PartNotDiscoverable]
\r
556 public class FieldExporter
\r
559 public object Field = null;
\r
562 [PartNotDiscoverable]
\r
563 public class MethodExporter
\r
566 public void Method() { }
\r
569 [PartNotDiscoverable]
\r
571 public class TypeExporter
\r
576 public void GetExportedObjectAlwaysReturnsSameReference_ForProperty()
\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
586 public void GetExportedObjectAlwaysReturnsSameReference_ForField()
\r
588 var exporter = new FieldExporter();
\r
589 var cp = CreatePart(new FieldExporter());
\r
590 var ed = cp.ExportDefinitions.Single();
\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
600 public void GetExportedObjectAlwaysReturnsSameReference_ForMethod()
\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
610 public void GetExportedObjectAlwaysReturnsSameReference_ForType()
\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
620 [PartNotDiscoverable]
\r
621 public class MethodWithoutContractName
\r
624 public void MethodWithoutContractNameNotAllowed()
\r
629 public interface IContract
\r
634 [AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = false)]
\r
635 public class CustomImportAttributeInvalidTarget : ImportAttribute
\r
637 public CustomImportAttributeInvalidTarget()
\r
638 : base(typeof(IContract))
\r
643 [PartNotDiscoverable]
\r
644 public class ImportWithCustomImport
\r
647 IContract ImportWithCustomAttributeImport { get; set; }
\r
650 [PartNotDiscoverable]
\r
651 public class ImportWithCustomImportInvalidTarget
\r
653 [CustomImportAttributeInvalidTarget]
\r
654 void InvalidImport() { }
\r
658 public void ImportDefinitions_ImportWithCustomAttributeImports()
\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
665 Assert.AreEqual(AttributedModelServices.GetContractName(typeof(IContract)), import.ContractName);
\r
666 Assert.AreEqual(AttributedModelServices.GetTypeIdentity(typeof(IContract)), import.RequiredTypeIdentity);
\r
670 public void ImportDefinitions_ImportWithCustomImportInvalidTarget_ShouldbeIgnored()
\r
672 var part = CreatePart(typeof(ImportWithCustomImportInvalidTarget));
\r
673 Assert.AreEqual(part.ImportDefinitions.Count(), 0);
\r
676 [PartNotDiscoverable]
\r
677 public class ImportManyWithCustomImportMany
\r
680 IContract ImportManyWithCustomAttributeImportMany { get; set; }
\r
683 [PartNotDiscoverable]
\r
684 public class ImportManyWithCustomImportManyInvalidTarget
\r
687 void InvalidImportMany() { }
\r
691 public void ImportDefinitions_ImportManyWithCustomAttributeImportManys()
\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
698 Assert.AreEqual(AttributedModelServices.GetContractName(typeof(IContract)), import.ContractName);
\r
699 Assert.AreEqual(AttributedModelServices.GetTypeIdentity(typeof(IContract)), import.RequiredTypeIdentity);
\r
703 public void ImportDefinitions_ImportManyWithCustomImportManyInvalidTarget_ShouldbeIgnored()
\r
705 var part = CreatePart(typeof(ImportManyWithCustomImportManyInvalidTarget));
\r
706 Assert.AreEqual(part.ImportDefinitions.Count(), 0);
\r
709 [AttributeUsage(AttributeTargets.Constructor, AllowMultiple = false, Inherited = false)]
\r
710 public class CustomImportingConstructorAttribute : ImportingConstructorAttribute
\r
712 public CustomImportingConstructorAttribute()
\r
718 [AttributeUsage(AttributeTargets.Constructor, AllowMultiple = true, Inherited = false)]
\r
719 public class CustomImportingConstructorAllowMultipleAttribute : ImportingConstructorAttribute
\r
721 public CustomImportingConstructorAllowMultipleAttribute()
\r
727 [AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = false)]
\r
728 public class CustomImportingConstructorInvalidTargetAttribute : ImportingConstructorAttribute
\r
730 public CustomImportingConstructorInvalidTargetAttribute()
\r
736 [PartNotDiscoverable]
\r
737 public class ImportingConstructorWithCustomImportingConstructor
\r
739 [CustomImportingConstructor]
\r
740 ImportingConstructorWithCustomImportingConstructor([Import] IContract argument) {}
\r
743 [PartNotDiscoverable]
\r
744 public class ImportingConstructorWithCustomImportingConstructorAllowMultiple
\r
746 [CustomImportingConstructorAllowMultiple]
\r
747 [CustomImportingConstructorAllowMultiple]
\r
748 ImportingConstructorWithCustomImportingConstructorAllowMultiple([Import] IContract argument) { }
\r
751 [PartNotDiscoverable]
\r
752 public class ImportingConstructorWithCustomImportingConstructorInvalidTarget
\r
754 [CustomImportingConstructorInvalidTarget]
\r
755 void InvalidImportingConstructor() { }
\r
759 public void ImportDefinitions_ImportingConstructorWithCustomAttributeImportingConstructors()
\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
766 Assert.AreEqual(AttributedModelServices.GetContractName(typeof(IContract)), import.ContractName);
\r
767 Assert.AreEqual(AttributedModelServices.GetTypeIdentity(typeof(IContract)), import.RequiredTypeIdentity);
\r
771 public void ImportDefinitions_ImportingConstructorWithCustomAttributeImportingConstructorsWithAllowMultiple_ShouldNotThrowInvalidOperation()
\r
773 var part = CreatePart(typeof(ImportingConstructorWithCustomImportingConstructorAllowMultiple));
\r
775 Assert.AreEqual(part.ImportDefinitions.Count(), 1);
\r
776 ContractBasedImportDefinition import = part.ImportDefinitions.First() as ContractBasedImportDefinition;
\r
777 Assert.IsNotNull(import);
\r
779 Assert.AreEqual(AttributedModelServices.GetContractName(typeof(IContract)), import.ContractName);
\r
780 Assert.AreEqual(AttributedModelServices.GetTypeIdentity(typeof(IContract)), import.RequiredTypeIdentity);
\r
784 public void ImportDefinitions_ImportingConstructorWithCustomImportingConstructorInvalidTarget_ShouldbeIgnored()
\r
786 var part = CreatePart(typeof(ImportingConstructorWithCustomImportingConstructorInvalidTarget));
\r
787 Assert.AreEqual(part.ImportDefinitions.Count(), 0);
\r
792 public class ClassWithMultipleParameterImports
\r
794 [ImportingConstructor]
\r
795 public ClassWithMultipleParameterImports([Import][ImportMany]string parameter)
\r
801 public class ClassWithMultipleFieldImports
\r
805 public string Field;
\r
809 public class ClassWithMultiplePropertyImports
\r
813 public string Property
\r
821 public class ClassWithMultipleCustomPropertyImports
\r
825 string Property { get; set; }
\r
829 public class ClassWithMultipleCustomPropertyImportManys
\r
833 string Property { get; set; }
\r
837 public class ClassWithMultipleCustomPropertyImportAndImportManys
\r
841 string Property { get; set; }
\r
845 public void ImportDefinitions_TypeWithMemberMarkedWithMultipleImports_ShouldTraceError()
\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
854 foreach (Type type in types)
\r
856 using (TraceContext context = new TraceContext(SourceLevels.Error))
\r
858 var definition = AttributedModelServices.CreatePartDefinition(type, null, true);
\r
859 definition.ImportDefinitions.Count();
\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
869 private Export[] CreateSimpleExports(object value)
\r
871 var export = ExportFactory.Create("NoContract", () => value);
\r
873 return new Export[] { export };
\r
876 private ReflectionComposablePart CreatePartWithExport()
\r
878 return CreatePart(typeof(StaticExportClass));
\r
881 private ReflectionComposablePart CreatePartWithNonRecomposableImport()
\r
883 return CreatePart(typeof(SingleImportWithAllowDefault));
\r
886 private ReflectionComposablePart CreatePartWithZeroOrOneImport()
\r
888 return CreatePart(typeof(SingleImportWithAllowDefault));
\r
891 private ReflectionComposablePart CreatePartWithExactlyOneImport()
\r
893 return CreatePart(typeof(SingleImport));
\r
896 private ReflectionComposablePart CreateDefaultPart()
\r
898 return CreatePart(new object());
\r
901 [PartNotDiscoverable]
\r
903 public class DisposablePart : IDisposable
\r
905 [Import(AllowDefault = true)]
\r
906 public int Foo { get; set; }
\r
908 public void Dispose() { }
\r
911 private ReflectionComposablePart CreateDefaultDisposablePart()
\r
913 return CreatePart(typeof(DisposablePart));
\r
916 private ReflectionComposablePart CreatePart(object instance)
\r
918 if (instance is Type)
\r
920 var definition = PartDefinitionFactory.CreateAttributed((Type)instance);
\r
922 return (ReflectionComposablePart)definition.CreatePart();
\r
926 var definition = PartDefinitionFactory.CreateAttributed(instance.GetType());
\r
928 return new ReflectionComposablePart(definition, instance);
\r