private static GrainReferenceCaster MakeCaster(Type interfaceType) { CodeGeneratorManager.GenerateAndCacheCodeForAssembly(interfaceType.Assembly); var genericInterfaceType = interfaceType.IsConstructedGenericType ? interfaceType.GetGenericTypeDefinition() : interfaceType; // Try to find the correct GrainReference type for this interface. Type grainReferenceType; if (!GrainToReferenceMapping.TryGetValue(genericInterfaceType, out grainReferenceType)) { throw new InvalidOperationException( string.Format("Cannot find generated GrainReference class for interface '{0}'", interfaceType)); } if (interfaceType.IsConstructedGenericType) { grainReferenceType = grainReferenceType.MakeGenericType(interfaceType.GenericTypeArguments); } // Get the grain reference constructor. var constructor = grainReferenceType.GetConstructors(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance) .Where( _ => { var parameters = _.GetParameters(); return(parameters.Length == 1 && parameters[0].ParameterType == typeof(GrainReference)); }).FirstOrDefault(); if (constructor == null) { throw new InvalidOperationException( string.Format( "Cannot find suitable constructor on generated reference type for interface '{0}'", interfaceType)); } // Construct an expression to construct a new instance of this grain reference when given another grain // reference. var createLambdaParameter = Expression.Parameter(typeof(GrainReference), "gr"); var createLambda = Expression.Lambda <Func <GrainReference, IAddressable> >( Expression.New(constructor, createLambdaParameter), createLambdaParameter); var grainRefParameter = Expression.Parameter(typeof(IAddressable), "grainRef"); var body = Expression.Call( GrainReferenceCastInternalMethodInfo, Expression.Constant(interfaceType), createLambda, grainRefParameter, Expression.Constant(GrainInterfaceData.GetGrainInterfaceId(interfaceType))); // Compile and return the reference casting lambda. var lambda = Expression.Lambda <GrainReferenceCaster>(body, grainRefParameter); return(lambda.Compile()); }
private static MemberDeclarationSyntax GenerateIsCompatibleMethod(Type grainType) { var method = TypeUtils.Method((GrainReference _) => _.IsCompatible(default(int))); var methodDeclaration = method.GetDeclarationSyntax(); var interfaceIdParameter = method.GetParameters()[0].Name.ToIdentifierName(); var interfaceIds = new HashSet <int>( new[] { GrainInterfaceData.GetGrainInterfaceId(grainType) }.Concat( GrainInterfaceData.GetRemoteInterfaces(grainType).Keys)); var returnValue = default(BinaryExpressionSyntax); foreach (var interfaceId in interfaceIds) { var check = SF.BinaryExpression( SyntaxKind.EqualsExpression, interfaceIdParameter, SF.LiteralExpression(SyntaxKind.NumericLiteralExpression, SF.Literal(interfaceId))); // If this is the first check, assign it, otherwise OR this check with the previous checks. returnValue = returnValue == null ? check : SF.BinaryExpression(SyntaxKind.LogicalOrExpression, returnValue, check); } return (methodDeclaration.AddBodyStatements(SF.ReturnStatement(returnValue)) .AddModifiers(SF.Token(SyntaxKind.OverrideKeyword))); }
/// <summary> /// Generates the class for the provided grain types. /// </summary> /// <param name="grainType"> /// The grain interface type. /// </param> /// <returns> /// The generated class. /// </returns> internal static TypeDeclarationSyntax GenerateClass(Type grainType) { var baseTypes = new List <BaseTypeSyntax> { SF.SimpleBaseType(typeof(IGrainMethodInvoker).GetTypeSyntax()) }; var grainTypeInfo = grainType.GetTypeInfo(); var genericTypes = grainTypeInfo.IsGenericTypeDefinition ? grainTypeInfo.GetGenericArguments() .Select(_ => SF.TypeParameter(_.ToString())) .ToArray() : new TypeParameterSyntax[0]; // Create the special method invoker marker attribute. var interfaceId = GrainInterfaceData.GetGrainInterfaceId(grainType); var interfaceIdArgument = SF.LiteralExpression(SyntaxKind.NumericLiteralExpression, SF.Literal(interfaceId)); var grainTypeArgument = SF.TypeOfExpression(grainType.GetTypeSyntax(includeGenericParameters: false)); var attributes = new List <AttributeSyntax> { CodeGeneratorCommon.GetGeneratedCodeAttributeSyntax(), SF.Attribute(typeof(MethodInvokerAttribute).GetNameSyntax()) .AddArgumentListArguments( SF.AttributeArgument(grainType.GetParseableName().GetLiteralExpression()), SF.AttributeArgument(interfaceIdArgument), SF.AttributeArgument(grainTypeArgument)), SF.Attribute(typeof(ExcludeFromCodeCoverageAttribute).GetNameSyntax()) }; var members = new List <MemberDeclarationSyntax> { GenerateInvokeMethod(grainType), GenerateInterfaceIdProperty(grainType) }; // If this is an IGrainExtension, make the generated class implement IGrainExtensionMethodInvoker. if (typeof(IGrainExtension).IsAssignableFrom(grainType)) { baseTypes.Add(SF.SimpleBaseType(typeof(IGrainExtensionMethodInvoker).GetTypeSyntax())); members.Add(GenerateExtensionInvokeMethod(grainType)); } var classDeclaration = SF.ClassDeclaration( CodeGeneratorCommon.ClassPrefix + TypeUtils.GetSuitableClassName(grainType) + ClassSuffix) .AddModifiers(SF.Token(SyntaxKind.InternalKeyword)) .AddBaseListTypes(baseTypes.ToArray()) .AddConstraintClauses(grainType.GetTypeConstraintSyntax()) .AddMembers(members.ToArray()) .AddAttributeLists(SF.AttributeList().AddAttributes(attributes.ToArray())); if (genericTypes.Length > 0) { classDeclaration = classDeclaration.AddTypeParameterListParameters(genericTypes); } return(classDeclaration); }
/// <summary> /// Generate Cast method in CodeDom and add it in reference class /// </summary> /// <param name="si">The service interface this grain reference type is being generated for</param> /// <param name="isFactory">whether the class being generated is a factory class rather than a grainref implementation</param> /// <param name="referenceClass">The class being generated for this grain reference type</param> protected override void AddCastMethods(GrainInterfaceData si, bool isFactory, CodeTypeDeclaration referenceClass) { string castImplCode; string checkCode = null; if (isFactory) { castImplCode = string.Format(@"{0}.Cast(grainRef)", FixupTypeName(si.ReferenceClassName)); if (si.IsSystemTarget) { checkCode = @"If Not ((Global.Orleans.Runtime.GrainReference)grainRef).IsInitializedSystemTarget Then Throw New InvalidOperationException(""InvalidCastException cast of a system target grain reference. Must have SystemTargetSilo set to the target silo address"") End If"; } } else { castImplCode = string.Format( @"CType(Global.Orleans.Runtime.GrainReference.CastInternal(GetType({0}), Function(gr As GrainReference) New {1}(gr), grainRef, {2}),{0})", FixupTypeName(si.InterfaceTypeName), // Interface type for references for this grain FixupTypeName(si.ReferenceClassName), // Concrete class for references for this grain GrainInterfaceData.GetGrainInterfaceId(si.Type)); } var methodImpl = string.Format(@" {3} Shared Function Cast(grainRef As Global.Orleans.Runtime.IAddressable) As {0} {1} Return {2} End Function", si.InterfaceTypeName.Replace("<", "(Of ").Replace(">", ")"), checkCode, castImplCode, "Public"); string getSystemTarget = null; if (isFactory && si.IsSystemTarget) { getSystemTarget = string.Format(@" Friend Shared Function GetSystemTarget(grainId As Global.Orleans.Runtime.GrainId, silo As Global.Orleans.Runtime.SiloAddress) As {0} Return Global.Orleans.Runtime.GrainReference.GetSystemTarget(grainId, silo, Cast) End Function", FixupTypeName(si.InterfaceTypeName)); } var castMethod = new CodeSnippetTypeMember(methodImpl + getSystemTarget); referenceClass.Members.Add(castMethod); }
/// <summary> /// Returns method declaration syntax for the InterfaceId property. /// </summary> /// <param name="grainType">The grain type.</param> /// <returns>Method declaration syntax for the InterfaceId property.</returns> private static MemberDeclarationSyntax GenerateInterfaceIdProperty(Type grainType) { var property = TypeUtils.Member((IGrainMethodInvoker _) => _.InterfaceId); var returnValue = SF.LiteralExpression( SyntaxKind.NumericLiteralExpression, SF.Literal(GrainInterfaceData.GetGrainInterfaceId(grainType))); return (SF.PropertyDeclaration(typeof(int).GetTypeSyntax(), property.Name) .AddAccessorListAccessors( SF.AccessorDeclaration(SyntaxKind.GetAccessorDeclaration) .AddBodyStatements(SF.ReturnStatement(returnValue))) .AddModifiers(SF.Token(SyntaxKind.PublicKeyword))); }
/// <summary> /// Generate Cast method in CodeDom and add it in reference class /// </summary> /// <param name="si">The service interface this grain reference type is being generated for</param> /// <param name="isFactory">whether the class being generated is a factory class rather than a grainref implementation</param> /// <param name="referenceClass">The class being generated for this grain reference type</param> protected override void AddCastMethods(GrainInterfaceData si, bool isFactory, CodeTypeDeclaration referenceClass) { string castImplCode; string checkCode = null; if (isFactory) { castImplCode = string.Format(@"{0}.Cast(grainRef)", si.ReferenceClassName); if (si.IsSystemTarget) { checkCode = @"if(!((global::Orleans.Runtime.GrainReference)grainRef).IsInitializedSystemTarget) throw new InvalidOperationException(""InvalidCastException cast of a system target grain reference. Must have SystemTargetSilo set to the target silo address"");"; } } else { castImplCode = string.Format( @"({0}) global::Orleans.Runtime.GrainReference.CastInternal(typeof({0}), (global::Orleans.Runtime.GrainReference gr) => {{ return new {1}(gr);}}, grainRef, {2})", si.InterfaceTypeName, // Interface type for references for this grain si.ReferenceClassName, // Concrete class for references for this grain GrainInterfaceData.GetGrainInterfaceId(si.Type)); } var methodImpl = string.Format(@" {3} static {0} Cast(global::Orleans.Runtime.IAddressable grainRef) {{ {1} return {2}; }}", si.InterfaceTypeName, checkCode, castImplCode, "public"); string getSystemTarget = null; if (isFactory && si.IsSystemTarget) { getSystemTarget = string.Format(@" internal static {0} GetSystemTarget(global::Orleans.Runtime.GrainId grainId, global::Orleans.Runtime.SiloAddress silo) {{ return global::Orleans.Runtime.GrainReference.GetSystemTarget(grainId, silo, Cast); }}", si.InterfaceTypeName); } var castMethod = new CodeSnippetTypeMember(methodImpl + getSystemTarget); referenceClass.Members.Add(castMethod); }
/// <summary> /// Generates switch cases for the provided grain type. /// </summary> /// <param name="grainType"> /// The grain type. /// </param> /// <param name="methodIdArgument"> /// The method id argument, which is used to select the correct switch label. /// </param> /// <param name="generateMethodHandler"> /// The function used to generate switch block statements for each method. /// </param> /// <returns> /// The switch cases for the provided grain type. /// </returns> public static SwitchSectionSyntax[] GenerateGrainInterfaceAndMethodSwitch( Type grainType, IdentifierNameSyntax methodIdArgument, Func <MethodInfo, StatementSyntax[]> generateMethodHandler) { var interfaces = GrainInterfaceData.GetRemoteInterfaces(grainType); interfaces[GrainInterfaceData.GetGrainInterfaceId(grainType)] = grainType; // Switch on interface id. var interfaceCases = new List <SwitchSectionSyntax>(); foreach (var @interface in interfaces) { var interfaceType = @interface.Value; var interfaceId = @interface.Key; var methods = GrainInterfaceData.GetMethods(interfaceType); var methodCases = new List <SwitchSectionSyntax>(); // Switch on method id. foreach (var method in methods) { // Generate switch case. var methodId = GrainInterfaceData.ComputeMethodId(method); var methodType = method; // Generate the switch label for this interface id. var methodIdSwitchLabel = SF.CaseSwitchLabel( SF.LiteralExpression(SyntaxKind.NumericLiteralExpression, SF.Literal(methodId))); // Generate the switch body. var methodInvokeStatement = generateMethodHandler(methodType); methodCases.Add( SF.SwitchSection().AddLabels(methodIdSwitchLabel).AddStatements(methodInvokeStatement)); } // Generate the switch label for this interface id. var interfaceIdSwitchLabel = SF.CaseSwitchLabel( SF.LiteralExpression(SyntaxKind.NumericLiteralExpression, SF.Literal(interfaceId))); // Generate the default case, which will throw a NotImplementedException. var errorMessage = SF.BinaryExpression( SyntaxKind.AddExpression, "interfaceId=".GetLiteralExpression(), SF.BinaryExpression( SyntaxKind.AddExpression, SF.LiteralExpression(SyntaxKind.NumericLiteralExpression, SF.Literal(interfaceId)), SF.BinaryExpression( SyntaxKind.AddExpression, ",methodId=".GetLiteralExpression(), methodIdArgument))); var throwStatement = SF.ThrowStatement( SF.ObjectCreationExpression(typeof(NotImplementedException).GetTypeSyntax()) .AddArgumentListArguments(SF.Argument(errorMessage))); var defaultCase = SF.SwitchSection().AddLabels(SF.DefaultSwitchLabel()).AddStatements(throwStatement); // Generate switch statements for the methods in this interface. var methodSwitchStatements = SF.SwitchStatement(methodIdArgument).AddSections(methodCases.ToArray()).AddSections(defaultCase); // Generate the switch section for this interface. interfaceCases.Add( SF.SwitchSection().AddLabels(interfaceIdSwitchLabel).AddStatements(methodSwitchStatements)); } return(interfaceCases.ToArray()); }
internal void AddReferenceClass(GrainInterfaceData interfaceData) { bool isObserver = IsObserver(interfaceData.Type); CodeTypeParameterCollection genericTypeParam = interfaceData.GenericTypeParams; // Declare factory class var factoryClass = new CodeTypeDeclaration(interfaceData.FactoryClassBaseName); if (genericTypeParam != null) { factoryClass.TypeParameters.AddRange(genericTypeParam); } factoryClass.IsClass = true; factoryClass.TypeAttributes = interfaceData.Type.IsPublic ? TypeAttributes.Public : TypeAttributes.NotPublic; MarkAsGeneratedCode(factoryClass); AddFactoryMethods(interfaceData, factoryClass); AddCastMethods(interfaceData, true, factoryClass); if (ShouldGenerateObjectRefFactory(interfaceData)) { AddCreateObjectReferenceMethods(interfaceData, factoryClass); } int factoryClassIndex = ReferencedNamespace.Types.Add(factoryClass); var referenceClass = new CodeTypeDeclaration(interfaceData.ReferenceClassBaseName); if (genericTypeParam != null) { referenceClass.TypeParameters.AddRange(genericTypeParam); } referenceClass.IsClass = true; referenceClass.BaseTypes.Add(new CodeTypeReference(typeof(GrainReference), CodeTypeReferenceOptions.GlobalReference)); referenceClass.BaseTypes.Add(new CodeTypeReference(typeof(IAddressable), CodeTypeReferenceOptions.GlobalReference)); var tref = new CodeTypeReference(interfaceData.Type); if (genericTypeParam != null) { foreach (CodeTypeParameter tp in genericTypeParam) { tref.TypeArguments.Add(tp.Name); } } referenceClass.BaseTypes.Add(tref); MarkAsGeneratedCode(referenceClass); referenceClass.TypeAttributes = TypeAttributes.NestedAssembly; referenceClass.CustomAttributes.Add( new CodeAttributeDeclaration(new CodeTypeReference(typeof(SerializableAttribute)))); referenceClass.CustomAttributes.Add( new CodeAttributeDeclaration( new CodeTypeReference(typeof(GrainReferenceAttribute), CodeTypeReferenceOptions.GlobalReference), new CodeAttributeArgument( new CodePrimitiveExpression(interfaceData.Type.Namespace + "." + TypeUtils.GetParameterizedTemplateName((interfaceData.Type)))))); var baseReferenceConstructor2 = new CodeConstructor { Attributes = MemberAttributes.FamilyOrAssembly }; baseReferenceConstructor2.Parameters.Add(new CodeParameterDeclarationExpression( new CodeTypeReference(typeof(GrainReference), CodeTypeReferenceOptions.GlobalReference), "reference")); baseReferenceConstructor2.BaseConstructorArgs.Add(new CodeVariableReferenceExpression("reference")); referenceClass.Members.Add(baseReferenceConstructor2); var baseReferenceConstructor3 = new CodeConstructor { Attributes = MemberAttributes.FamilyOrAssembly }; baseReferenceConstructor3.Parameters.Add(new CodeParameterDeclarationExpression("SerializationInfo", "info")); baseReferenceConstructor3.BaseConstructorArgs.Add(new CodeVariableReferenceExpression("info")); baseReferenceConstructor3.Parameters.Add(new CodeParameterDeclarationExpression("StreamingContext", "context")); baseReferenceConstructor3.BaseConstructorArgs.Add(new CodeVariableReferenceExpression("context")); referenceClass.Members.Add(baseReferenceConstructor3); var grainRef = new CodeTypeReference(typeof(GrainReference), CodeTypeReferenceOptions.GlobalReference); var refClassName = FixupTypeName(interfaceData.ReferenceClassName); // Copier, serializer, and deserializer for this type var copier = SerializerGenerationUtilities.GenerateCopier("_Copier", refClassName, genericTypeParam); copier.Statements.Add( new CodeMethodReturnStatement( new CodeCastExpression(refClassName, new CodeMethodInvokeExpression(new CodeTypeReferenceExpression(grainRef), "CopyGrainReference", new CodeVariableReferenceExpression("input"))))); referenceClass.Members.Add(copier); var serializer = SerializerGenerationUtilities.GenerateSerializer("_Serializer", refClassName, genericTypeParam); serializer.Statements.Add( new CodeMethodInvokeExpression( new CodeTypeReferenceExpression(grainRef), "SerializeGrainReference", new CodeVariableReferenceExpression("input"), new CodeArgumentReferenceExpression("stream"), new CodeArgumentReferenceExpression("expected"))); referenceClass.Members.Add(serializer); var deserializer = SerializerGenerationUtilities.GenerateDeserializer("_Deserializer", refClassName, genericTypeParam); deserializer.Statements.Add( new CodeMethodReturnStatement( new CodeMethodInvokeExpression( new CodeTypeReferenceExpression(refClassName), "Cast", new CodeCastExpression(grainRef, new CodeMethodInvokeExpression( new CodeTypeReferenceExpression(grainRef), "DeserializeGrainReference", new CodeArgumentReferenceExpression("expected"), new CodeArgumentReferenceExpression("stream")))))); referenceClass.Members.Add(deserializer); // this private class is the "implementation class" for the interface reference type ReferencedNamespace.Types[factoryClassIndex].Members.Add(referenceClass); AddCastMethods(interfaceData, false, referenceClass); var interfaceId = GrainInterfaceData.GetGrainInterfaceId(interfaceData.Type); var interfaceIdMethod = new CodeMemberProperty { Name = "InterfaceId", Type = new CodeTypeReference(typeof(int)), Attributes = MemberAttributes.Family | MemberAttributes.Override, HasSet = false, HasGet = true }; interfaceIdMethod.GetStatements.Add(new CodeMethodReturnStatement(new CodePrimitiveExpression(interfaceId))); referenceClass.Members.Add(interfaceIdMethod); var left = new CodeBinaryOperatorExpression( new CodeArgumentReferenceExpression("interfaceId"), CodeBinaryOperatorType.ValueEquality, new CodePropertyReferenceExpression(new CodeThisReferenceExpression(), "InterfaceId")); var interfaceList = GrainInterfaceData.GetRemoteInterfaces(interfaceData.Type); foreach (int iid in interfaceList.Keys) { if (iid == interfaceId) { continue; // already covered the main interfaces } left = new CodeBinaryOperatorExpression( left, CodeBinaryOperatorType.BooleanOr, new CodeBinaryOperatorExpression( new CodeArgumentReferenceExpression("interfaceId"), CodeBinaryOperatorType.ValueEquality, new CodePrimitiveExpression(iid))); } var interfaceIsCompatibleMethod = new CodeMemberMethod { Name = "IsCompatible", ReturnType = new CodeTypeReference(typeof(bool)) }; interfaceIsCompatibleMethod.Parameters.Add(new CodeParameterDeclarationExpression(new CodeTypeReference(typeof(int)), "interfaceId")); interfaceIsCompatibleMethod.Attributes = MemberAttributes.Public | MemberAttributes.Override; interfaceIsCompatibleMethod.Statements.Add(new CodeMethodReturnStatement(left)); referenceClass.Members.Add(interfaceIsCompatibleMethod); var interfaceNameMethod = new CodeMemberProperty { Name = "InterfaceName", Type = new CodeTypeReference(typeof(string)), Attributes = MemberAttributes.Family | MemberAttributes.Override, HasSet = false, HasGet = true }; interfaceNameMethod.GetStatements.Add(new CodeMethodReturnStatement(new CodePrimitiveExpression(FixupTypeName(interfaceData.TypeFullName)))); referenceClass.Members.Add(interfaceNameMethod); var invokerClassName = interfaceData.InvokerClassName; var getMethodNameMethod = new CodeMemberMethod { Name = "GetMethodName", ReturnType = new CodeTypeReference(typeof(string)) }; getMethodNameMethod.Parameters.Add(new CodeParameterDeclarationExpression(new CodeTypeReference(typeof(int)), "interfaceId")); getMethodNameMethod.Parameters.Add(new CodeParameterDeclarationExpression(new CodeTypeReference(typeof(int)), "methodId")); getMethodNameMethod.Attributes = MemberAttributes.Family | MemberAttributes.Override; var methodInvokerName = string.Format("{0}.GetMethodName", FixupTypeName(invokerClassName)); getMethodNameMethod.Statements.Add( new CodeMethodReturnStatement( new CodeMethodInvokeExpression( null, methodInvokerName, new CodeArgumentReferenceExpression("interfaceId"), new CodeArgumentReferenceExpression("methodId")))); referenceClass.Members.Add(getMethodNameMethod); CodeTypeDeclaration invokerClass = GetInvokerClass(interfaceData, true); invokerClass.TypeAttributes = TypeAttributes.NotPublic; ReferencedNamespace.Types.Add(invokerClass); ReferencedNamespace.Imports.Add(new CodeNamespaceImport("System")); ReferencedNamespace.Imports.Add(new CodeNamespaceImport("System.Net")); ReferencedNamespace.Imports.Add(new CodeNamespaceImport("System.Runtime.Serialization")); ReferencedNamespace.Imports.Add(new CodeNamespaceImport("System.Runtime.Serialization.Formatters.Binary")); ReferencedNamespace.Imports.Add(new CodeNamespaceImport("System.IO")); ReferencedNamespace.Imports.Add(new CodeNamespaceImport("System.Collections.Generic")); MethodInfo[] methods = GrainInterfaceData.GetMethods(interfaceData.Type); AddMethods(methods, referenceClass, genericTypeParam, isObserver); }
protected override void AddGetGrainMethods(GrainInterfaceData iface, CodeTypeDeclaration factoryClass) { RecordReferencedNamespaceAndAssembly(typeof(GrainId)); RecordReferencedNamespaceAndAssembly(iface.Type); var interfaceId = GrainInterfaceData.GetGrainInterfaceId(iface.Type); var interfaceName = iface.InterfaceTypeName; Action <string> add = codeFmt => factoryClass.Members.Add(new CodeSnippetTypeMember( String.Format(codeFmt, FixupTypeName(interfaceName), interfaceId))); bool hasKeyExt = GrainInterfaceData.UsesPrimaryKeyExtension(iface.Type); bool isGuidKey = typeof(IGrainWithGuidKey).IsAssignableFrom(iface.Type); bool isLongKey = typeof(IGrainWithIntegerKey).IsAssignableFrom(iface.Type); bool isStringKey = typeof(IGrainWithStringKey).IsAssignableFrom(iface.Type); bool isDefaultKey = !(isGuidKey || isStringKey || isLongKey); if (isDefaultKey && hasKeyExt) { // the programmer has specified [ExtendedPrimaryKey] on the interface. add( @" Public Shared Function GetGrain(primaryKey as System.Int64, keyExt as System.String) As {0} Return Cast(Global.Orleans.CodeGeneration.GrainFactoryBase.MakeKeyExtendedGrainReferenceInternal(GetType({0}), {1}, primaryKey, keyExt)) End Function"); add( @" Public Shared Function GetGrain(primaryKey as System.Int64, keyExt as System.String, grainClassNamePrefix As System.String) As {0} Return Cast(Global.Orleans.CodeGeneration.GrainFactoryBase.MakeKeyExtendedGrainReferenceInternal(GetType({0}), {1}, primaryKey, keyExt, grainClassNamePrefix)) End Function"); add( @" Public Shared Function GetGrain(primaryKey As System.Guid, keyExt as System.String) As {0} Return Cast(Global.Orleans.CodeGeneration.GrainFactoryBase.MakeKeyExtendedGrainReferenceInternal(GetType({0}), {1}, primaryKey, keyExt)) End Function"); add( @" Public Shared Function GetGrain(primaryKey As System.Guid, keyExt as System.String, grainClassNamePrefix As System.String) As {0} Return Cast(Global.Orleans.CodeGeneration.GrainFactoryBase.MakeKeyExtendedGrainReferenceInternal(GetType({0}), {1}, primaryKey, keyExt,grainClassNamePrefix)) End Function"); } else { // the programmer has not specified [ExplicitPlacement] on the interface nor [ExtendedPrimaryKey]. if (isLongKey || isDefaultKey) { add( @" Public Shared Function GetGrain(primaryKey as System.Int64) As {0} Return Cast(Global.Orleans.CodeGeneration.GrainFactoryBase.MakeGrainReferenceInternal(GetType({0}), {1}, primaryKey)) End Function"); add( @" Public Shared Function GetGrain(primaryKey as System.Int64, grainClassNamePrefix As System.String) As {0} Return Cast(Global.Orleans.CodeGeneration.GrainFactoryBase.MakeGrainReferenceInternal(GetType({0}), {1}, primaryKey, grainClassNamePrefix)) End Function"); } if (isGuidKey || isDefaultKey) { add( @" Public Shared Function GetGrain(primaryKey As System.Guid) As {0} Return Cast(Global.Orleans.CodeGeneration.GrainFactoryBase.MakeGrainReferenceInternal(GetType({0}), {1}, primaryKey)) End Function"); add( @" Public Shared Function GetGrain(primaryKey As System.Guid, grainClassNamePrefix As System.String) As {0} Return Cast(Global.Orleans.CodeGeneration.GrainFactoryBase.MakeGrainReferenceInternal(GetType({0}), {1}, primaryKey, grainClassNamePrefix)) End Function"); } if (isStringKey) { add( @" Public Shared Function GetGrain(primaryKey As System.String) As {0} Return Cast(Global.Orleans.CodeGeneration.GrainFactoryBase.MakeGrainReferenceInternal(GetType({0}), {1}, primaryKey)) End Function"); add( @" Public Shared Function GetGrain(primaryKey As System.String, grainClassNamePrefix As System.String) As {0} Return Cast(Global.Orleans.CodeGeneration.GrainFactoryBase.MakeGrainReferenceInternal(GetType({0}), {1}, primaryKey, grainClassNamePrefix)) End Function"); } } }
protected override void AddGetGrainMethods(GrainInterfaceData iface, CodeTypeDeclaration factoryClass) { RecordReferencedNamespaceAndAssembly(typeof(GrainId)); RecordReferencedNamespaceAndAssembly(iface.Type); var interfaceId = GrainInterfaceData.GetGrainInterfaceId(iface.Type); Action <string> add = codeFmt => factoryClass.Members.Add( new CodeSnippetTypeMember(String.Format(codeFmt, iface.InterfaceTypeName))); bool isGuidCompoundKey = typeof(IGrainWithGuidCompoundKey).IsAssignableFrom(iface.Type); bool isLongCompoundKey = typeof(IGrainWithIntegerCompoundKey).IsAssignableFrom(iface.Type); bool isGuidKey = typeof(IGrainWithGuidKey).IsAssignableFrom(iface.Type); bool isLongKey = typeof(IGrainWithIntegerKey).IsAssignableFrom(iface.Type); bool isStringKey = typeof(IGrainWithStringKey).IsAssignableFrom(iface.Type); bool isDefaultKey = !(isGuidKey || isStringKey || isLongKey); if (isLongCompoundKey) { // the programmer has specified [ExtendedPrimaryKey] on the interface. add(@" [System.Obsolete(""This method has been deprecated. Please use GrainFactory.GetGrain<{0}> instead."")] public static {0} GetGrain(long primaryKey, string keyExt) {{ return Cast(global::Orleans.CodeGeneration.GrainFactoryBase.MakeKeyExtendedGrainReferenceInternal(typeof({0}), primaryKey, keyExt)); }}"); add(@" [System.Obsolete(""This method has been deprecated. Please use GrainFactory.GetGrain<{0}> instead."")] public static {0} GetGrain(long primaryKey, string keyExt, string grainClassNamePrefix) {{ return Cast(global::Orleans.CodeGeneration.GrainFactoryBase.MakeKeyExtendedGrainReferenceInternal(typeof({0}), primaryKey, keyExt, grainClassNamePrefix)); }}"); } else if (isGuidCompoundKey) { add(@" [System.Obsolete(""This method has been deprecated. Please use GrainFactory.GetGrain<{0}> instead."")] public static {0} GetGrain(System.Guid primaryKey, string keyExt) {{ return Cast(global::Orleans.CodeGeneration.GrainFactoryBase.MakeKeyExtendedGrainReferenceInternal(typeof({0}), primaryKey, keyExt)); }}"); add(@" [System.Obsolete(""This method has been deprecated. Please use GrainFactory.GetGrain<{0}> instead."")] public static {0} GetGrain(System.Guid primaryKey, string keyExt, string grainClassNamePrefix) {{ return Cast(global::Orleans.CodeGeneration.GrainFactoryBase.MakeKeyExtendedGrainReferenceInternal(typeof({0}), primaryKey, keyExt, grainClassNamePrefix)); }}"); } else { // the programmer has not specified [ExplicitPlacement] on the interface nor [ExtendedPrimaryKey]. if (isLongKey || isDefaultKey) { add(@" [System.Obsolete(""This method has been deprecated. Please use GrainFactory.GetGrain<{0}> instead."")] public static {0} GetGrain(long primaryKey) {{ return Cast(global::Orleans.CodeGeneration.GrainFactoryBase.MakeGrainReferenceInternal(typeof({0}), primaryKey)); }}"); add(@" [System.Obsolete(""This method has been deprecated. Please use GrainFactory.GetGrain<{0}> instead."")] public static {0} GetGrain(long primaryKey, string grainClassNamePrefix) {{ return Cast(global::Orleans.CodeGeneration.GrainFactoryBase.MakeGrainReferenceInternal(typeof({0}), primaryKey, grainClassNamePrefix)); }}"); } if (isGuidKey || isDefaultKey) { add(@" [System.Obsolete(""This method has been deprecated. Please use GrainFactory.GetGrain<{0}> instead."")] public static {0} GetGrain(System.Guid primaryKey) {{ return Cast(global::Orleans.CodeGeneration.GrainFactoryBase.MakeGrainReferenceInternal(typeof({0}), primaryKey)); }}"); add(@" [System.Obsolete(""This method has been deprecated. Please use GrainFactory.GetGrain<{0}> instead."")] public static {0} GetGrain(System.Guid primaryKey, string grainClassNamePrefix) {{ return Cast(global::Orleans.CodeGeneration.GrainFactoryBase.MakeGrainReferenceInternal(typeof({0}), primaryKey, grainClassNamePrefix)); }}"); } if (isStringKey) { add(@" [System.Obsolete(""This method has been deprecated. Please use GrainFactory.GetGrain<{0}> instead."")] public static {0} GetGrain(System.String primaryKey) {{ return Cast(global::Orleans.CodeGeneration.GrainFactoryBase.MakeGrainReferenceInternal(typeof({0}), primaryKey)); }}"); add(@" [System.Obsolete(""This method has been deprecated. Please use GrainFactory.GetGrain<{0}> instead."")] public static {0} GetGrain(System.String primaryKey, string grainClassNamePrefix) {{ return Cast(global::Orleans.CodeGeneration.GrainFactoryBase.MakeGrainReferenceInternal(typeof({0}), primaryKey, grainClassNamePrefix)); }}"); } } }