public void MakeGenericTypeOfBoundTypesResultsInBoundType() { //-- arrange TypeMember typeInt = typeof(int); TypeMember typeString = typeof(string); TypeMember typeIDictionaryOpen = typeof(IDictionary <,>); //-- act TypeMember constructedType = typeIDictionaryOpen.MakeGenericType(typeInt, typeString); //-- assert constructedType.ClrBinding.Should().NotBeNull(); constructedType.ClrBinding.Should().BeSameAs(typeof(IDictionary <int, string>)); constructedType.Should().NotBeNull(); constructedType.IsGenericType.Should().BeTrue(); constructedType.IsGenericTypeDefinition.Should().BeFalse(); constructedType.GenericTypeDefinition.Should().BeSameAs(typeIDictionaryOpen); constructedType.GenericTypeArguments.Count.Should().Be(2); constructedType.GenericTypeArguments[0].Should().BeSameAs(typeInt); constructedType.GenericTypeArguments[1].Should().BeSameAs(typeString); }
//----------------------------------------------------------------------------------------------------------------------------------------------------- private void ImplementActivationInterface( TypeMember productType, TypeMember activationContract, MethodSignature constructorSignature, TypeMember artifactType) { var parameterCount = constructorSignature.Parameters.Count; var iConstructorGenericParameters = constructorSignature.Parameters.Select(p => p.Type) .Append(activationContract); TypeMember iConstructorInterfaceOpen = _s_iConstructorByParameterCount[parameterCount]; TypeMember iConstructorInterfaceClosed = iConstructorInterfaceOpen.MakeGenericType(iConstructorGenericParameters.ToArray()); artifactType.Interfaces.Add(iConstructorInterfaceClosed); var factoryMethod = new MethodMember( MemberVisibility.Public, MemberModifier.None, nameof(IConstructor <object> .NewInstance), new MethodSignature { ReturnValue = new MethodParameter { Type = activationContract } } ); factoryMethod.Signature.Parameters.AddRange(constructorSignature.Parameters); var newObjectExpression = new NewObjectExpression { Type = productType, ConstructorCall = new MethodCallExpression() }; newObjectExpression.ConstructorCall.Arguments.AddRange( constructorSignature.Parameters.Select(p => new Argument { Expression = new ParameterExpression { Parameter = p } })); factoryMethod.Body = new BlockStatement( new ReturnStatement { Expression = newObjectExpression } ); ImplementSingletonMethod(productType, activationContract, constructorSignature, artifactType); artifactType.Members.Add(factoryMethod); }
public void MakeGenericTypeOfMixedBoundAndGeneratedTypesResultsInGeneratedType() { //-- arrange TypeMember typeKey = typeof(int); TypeMember typeValue = new TypeMember(MemberVisibility.Public, TypeMemberKind.Class, "ClassValue"); TypeMember typeIDictionaryOpen = typeof(IDictionary <,>); //-- act TypeMember constructedType = typeIDictionaryOpen.MakeGenericType(typeKey, typeValue); //-- assert constructedType.ClrBinding.Should().BeNull(); constructedType.Should().NotBeNull(); constructedType.IsGenericType.Should().BeTrue(); constructedType.IsGenericTypeDefinition.Should().BeFalse(); constructedType.GenericTypeDefinition.Should().BeSameAs(typeIDictionaryOpen); constructedType.GenericTypeArguments.Count.Should().Be(2); constructedType.GenericTypeArguments[0].Should().BeSameAs(typeKey); constructedType.GenericTypeArguments[1].Should().BeSameAs(typeValue); }
public void Usings_GenericTypeNames_RulesApplyRecursively() { //-- arrange var generatorUnderTest = new CSharpSyntaxGenerator(); var typeFirstClassA = new TypeMember(new TypeGeneratorInfo(this.GetType()), "My.First", MemberVisibility.Public, TypeMemberKind.Class, "ClassA"); var typeFirstClassList = new TypeMember(new TypeGeneratorInfo(this.GetType()), "My.First", MemberVisibility.Public, TypeMemberKind.Class, "List", new TypeMember(new TypeGeneratorInfo(this.GetType()), null, MemberVisibility.Public, TypeMemberKind.GenericParameter, "T")); var typeSecondClassA = new TypeMember(new TypeGeneratorInfo(this.GetType()), "My.Second", MemberVisibility.Public, TypeMemberKind.Class, "ClassA"); var typeSecondClassB = new TypeMember(new TypeGeneratorInfo(this.GetType()), "My.Second", MemberVisibility.Public, TypeMemberKind.Class, "ClassB"); var typeThirdClassC = new TypeMember(new TypeGeneratorInfo(this.GetType()), "My.Third", MemberVisibility.Public, TypeMemberKind.Class, "ClassC"); TypeMember typeGenericDictionary = typeof(Dictionary <,>); TypeMember typeGenericList = typeof(List <>); var typeDictionaryOfFirstClassASecondClassA = typeGenericDictionary.MakeGenericType(typeFirstClassA, typeSecondClassA); var typeListOfSecondClassB = typeGenericList.MakeGenericType(typeSecondClassB); typeThirdClassC.Members.Add(new PropertyMember( typeThirdClassC, MemberVisibility.Public, MemberModifier.None, typeDictionaryOfFirstClassASecondClassA, "SecondByFirst")); typeThirdClassC.Members.Add(new PropertyMember( typeThirdClassC, MemberVisibility.Public, MemberModifier.None, typeListOfSecondClassB, "ListOfB")); //-- act SyntaxTree syntax = generatorUnderTest.GenerateSyntax( typesToCompile: new[] { typeFirstClassA, typeFirstClassList, typeSecondClassA, typeSecondClassB, typeThirdClassC }, allReferencedTypes: new[] { typeFirstClassA, typeFirstClassList, typeSecondClassA, typeSecondClassB, typeDictionaryOfFirstClassASecondClassA, typeListOfSecondClassB }); //-- assert syntax.Should().BeEquivalentToCode(@" using System.Collections.Generic; using My.Second; namespace My.First { public class ClassA { } public class List<T> { } } namespace My.Second { public class ClassA { } public class ClassB { } } namespace My.Third { public class ClassC { public Dictionary<My.First.ClassA, My.Second.ClassA> SecondByFirst { get; } public System.Collections.Generic.List<ClassB> ListOfB { get; } } } "); }