internal void AddEntry(int interfaceId, Type iface, int grainTypeCode, string grainInterface, string grainClass, string assembly, bool isGenericGrainClass, PlacementStrategy placement, bool primaryImplementation = false) { lock (this) { GrainInterfaceData grainInterfaceData; if (table.ContainsKey(interfaceId)) { grainInterfaceData = table[interfaceId]; } else { grainInterfaceData = new GrainInterfaceData(interfaceId, iface, grainInterface); table[interfaceId] = grainInterfaceData; var interfaceTypeKey = GetTypeKey(iface, isGenericGrainClass); typeToInterfaceData[interfaceTypeKey] = grainInterfaceData; } var implementation = new GrainClassData(grainTypeCode, grainClass, isGenericGrainClass, grainInterfaceData, placement); if (!implementationIndex.ContainsKey(grainTypeCode)) implementationIndex.Add(grainTypeCode, implementation); grainInterfaceData.AddImplementation(implementation, primaryImplementation); if (primaryImplementation) { primaryImplementations[grainInterface] = grainClass; } else { if (!primaryImplementations.ContainsKey(grainInterface)) primaryImplementations.Add(grainInterface, grainClass); } if (localTestMode) { if (!loadedGrainAsemblies.Contains(assembly)) loadedGrainAsemblies.Add(assembly); } } }
protected override void AddCreateObjectReferenceMethods(GrainInterfaceData grainInterfaceData, CodeTypeDeclaration factoryClass) { var fieldImpl = @"Private Shared methodInvoker As Global.Orleans.CodeGeneration.IGrainMethodInvoker"; var invokerField = new CodeSnippetTypeMember(fieldImpl); factoryClass.Members.Add(invokerField); var methodImpl = String.Format(@" Public Shared Async Function CreateObjectReference(obj As {0}) As System.Threading.Tasks.Task(Of {0}) If methodInvoker Is Nothing Then : methodInvoker = New {2}() : End If Return {1}.Cast(Await Global.Orleans.Runtime.GrainReference.CreateObjectReference(obj, methodInvoker)) End Function", grainInterfaceData.TypeName, grainInterfaceData.FactoryClassName, grainInterfaceData.InvokerClassName); var createObjectReferenceMethod = new CodeSnippetTypeMember(methodImpl); factoryClass.Members.Add(createObjectReferenceMethod); methodImpl = String.Format(@" Public Shared Function DeleteObjectReference(reference As {0}) As System.Threading.Tasks.Task Return Global.Orleans.Runtime.GrainReference.DeleteObjectReference(reference) End Function", grainInterfaceData.TypeName); var deleteObjectReferenceMethod = new CodeSnippetTypeMember(methodImpl); factoryClass.Members.Add(deleteObjectReferenceMethod); }
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)); }}"); } } }
protected override void AddCreateObjectReferenceMethods(GrainInterfaceData grainInterfaceData, CodeTypeDeclaration factoryClass) { var fieldImpl = @" private static global::Orleans.CodeGeneration.IGrainMethodInvoker methodInvoker;"; var invokerField = new CodeSnippetTypeMember(fieldImpl); factoryClass.Members.Add(invokerField); var methodImpl = String.Format(@" public async static System.Threading.Tasks.Task<{0}> CreateObjectReference({0} obj) {{ if (methodInvoker == null) methodInvoker = new {2}(); return {1}.Cast(await global::Orleans.Runtime.GrainReference.CreateObjectReference(obj, methodInvoker)); }}", grainInterfaceData.TypeName, grainInterfaceData.FactoryClassName, grainInterfaceData.InvokerClassName); var createObjectReferenceMethod = new CodeSnippetTypeMember(methodImpl); factoryClass.Members.Add(createObjectReferenceMethod); methodImpl = String.Format(@" public static System.Threading.Tasks.Task DeleteObjectReference({0} reference) {{ return global::Orleans.Runtime.GrainReference.DeleteObjectReference(reference); }}", grainInterfaceData.TypeName); var deleteObjectReferenceMethod = new CodeSnippetTypeMember(methodImpl); factoryClass.Members.Add(deleteObjectReferenceMethod); }
/// <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) { throw new NotImplementedException("AddCastMethods"); }
protected override string GetInvokerImpl(GrainInterfaceData si, CodeTypeDeclaration invokerClass, Type grainType, GrainInterfaceInfo grainInterfaceInfo, bool isClient) { throw new NotImplementedException("GetInvokerImpl"); }
protected override CodeTypeDeclaration GetStateClass(GrainInterfaceData grainInterfaceData, Action<Type> referred, string stateClassBaseName, string stateClassName, out bool hasStateClass) { var sourceType = grainInterfaceData.Type; stateClassName = FixupTypeName(stateClassName); CodeTypeParameterCollection genericTypeParams = grainInterfaceData.GenericTypeParams; Func<Type, bool> nonamespace = t => false; Type persistentInterface = GetPersistentInterface(sourceType); Dictionary<string, PropertyInfo> asyncProperties = GrainInterfaceData.GetPersistentProperties(persistentInterface) .ToDictionary(p => p.Name.Substring(p.Name.LastIndexOf('.') + 1), p => p); Dictionary<string, string> properties = asyncProperties.ToDictionary(p => p.Key, p => GetGenericTypeName(GrainInterfaceData.GetPromptType(p.Value.PropertyType), referred, nonamespace)); hasStateClass = properties.Count > 0; if (!hasStateClass) return null; var typeAccess = (persistentInterface != null && !persistentInterface.IsPublic) ? "internal" : "public"; StartNewLine(); StartNewLine(); generatedCode.AppendFormat(@"[<System.CodeDom.Compiler.GeneratedCodeAttribute(""{0}"", ""{1}"")>]", CODE_GENERATOR_NAME, CodeGeneratorVersion); StartNewLine(); generatedCode.AppendFormat(@"[<System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverageAttribute()>]"); StartNewLine(); generatedCode.AppendFormat(@"[<System.SerializableAttribute()>]"); StartNewLine(); var grainName = grainInterfaceData.Type.Namespace + "." + TypeUtils.GetParameterizedTemplateName(grainInterfaceData.Type); generatedCode.AppendFormat(@"[<global.Orleans.CodeGeneration.GrainStateAttribute(""{0}"")>]", grainName); StartNewLine(); generatedCode.AppendFormat(@"type {0} {1}", typeAccess, stateClassBaseName); if (genericTypeParams != null && genericTypeParams.Count > 0) { generatedCode.Append('<'); for (int p = 0; p < genericTypeParams.Count; ++p) { if (p > 0) generatedCode.Append(','); CodeTypeParameter param = genericTypeParams[p]; generatedCode.Append('\'').Append(param.Name); } generatedCode.Append('>'); } generatedCode.AppendFormat(@"() ="); IncreaseIndent(); StartNewLine(); generatedCode.AppendFormat(@"inherit global.Orleans.CodeGeneration.GrainState(""{0}"")", grainName); StartNewLine(); var declaringTypes = new Dictionary<string, List<KeyValuePair<string, PropertyInfo>>>(); foreach (var pair in asyncProperties) { var dtName = GetGenericTypeName(pair.Value.DeclaringType, referred, nonamespace); if (!declaringTypes.ContainsKey(dtName)) declaringTypes.Add(dtName, new List<KeyValuePair<string, PropertyInfo>>()); var lst = declaringTypes[dtName]; lst.Add(pair); } foreach (var declaringType in declaringTypes) { StartNewLine(); generatedCode.AppendFormat(@"interface {0} with", declaringType.Key); IncreaseIndent(); foreach (var pair in declaringType.Value) { var propertyType = pair.Value.PropertyType; bool noCreateNew = propertyType.IsPrimitive || typeof(string).IsAssignableFrom(propertyType) // Primative types || propertyType.IsAbstract || propertyType.IsInterface || propertyType.IsGenericParameter // No concrete implementation || propertyType.GetConstructor(Type.EmptyTypes) == null; // No default constructor var initExpr = noCreateNew ? string.Format("Unchecked.defaultof<{0}>", GetGenericTypeName(propertyType, referred, nonamespace)) : string.Format("{0}()", GetGenericTypeName(propertyType, referred, nonamespace)); StartNewLine(); generatedCode.AppendFormat(@"override val {0} = {1} with get,set", pair.Key, initExpr); } DecreaseIndent(); } GenerateSetAll(asyncProperties, referred); GenerateAsDictionary(asyncProperties, referred); GenerateToString(stateClassName, asyncProperties, referred); // Generate the serialization members. StartNewLine(); StartNewLine(); generatedCode.AppendFormat(@"[<global.Orleans.CodeGeneration.CopierMethodAttribute()>]"); StartNewLine(); generatedCode.AppendFormat(@"static member public _Copier(original:obj) : obj ="); IncreaseIndent(); StartNewLine(); generatedCode.AppendFormat(@"let input = original :?> {0}", stateClassBaseName); StartNewLine(); generatedCode.AppendFormat(@"input.DeepCopy() :> obj"); DecreaseIndent(); StartNewLine(); StartNewLine(); generatedCode.AppendFormat(@"[<global.Orleans.CodeGeneration.SerializerMethodAttribute()>]"); StartNewLine(); generatedCode.AppendFormat(@"static member public _Serializer(original:obj, stream:global.Orleans.Serialization.BinaryTokenStreamWriter, expected:System.Type) : unit ="); IncreaseIndent(); StartNewLine(); generatedCode.AppendFormat(@"let input = original :?> {0}", stateClassBaseName); StartNewLine(); generatedCode.AppendFormat(@"input.SerializeTo(stream)"); DecreaseIndent(); StartNewLine(); StartNewLine(); generatedCode.AppendFormat(@"[<global.Orleans.CodeGeneration.DeserializerMethodAttribute()>]"); StartNewLine(); generatedCode.AppendFormat(@"static member public _Deserializer(expected:System.Type, stream:global.Orleans.Serialization.BinaryTokenStreamReader) : obj ="); IncreaseIndent(); StartNewLine(); generatedCode.AppendFormat(@"let result = {0}()", stateClassBaseName); StartNewLine(); generatedCode.AppendFormat(@"result.DeserializeFrom(stream)"); StartNewLine(); generatedCode.AppendFormat(@"result :> obj"); DecreaseIndent(); DecreaseIndent(); return null; }
internal GrainClassData(int grainTypeCode, string grainClass, bool isGeneric, GrainInterfaceData interfaceData, PlacementStrategy placement) { GrainTypeCode = grainTypeCode; GrainClass = grainClass; this.isGeneric = isGeneric; this.interfaceData = interfaceData; genericClassNames = new Dictionary<string, string>(); // TODO: initialize only for generic classes placementStrategy = placement ?? PlacementStrategy.GetDefault(); }
protected virtual void AddCreateObjectReferenceMethods(GrainInterfaceData grainInterfaceData, CodeTypeDeclaration factoryClass) { throw new NotImplementedException("GrainNamespace.AddCreateObjectReferenceMethods"); }
protected virtual CodeTypeDeclaration GetStateClass( GrainInterfaceData grainInterfaceData, Action<Type> referred, string stateClassBaseName, string stateClassName, out bool hasStateClass) { var sourceType = grainInterfaceData.Type; stateClassName = FixupTypeName(stateClassName); CodeTypeParameterCollection genericTypeParams = grainInterfaceData.GenericTypeParams; Func<Type, bool> nonamespace = t => CurrentNamespace == t.Namespace || ReferencedNamespaces.Contains(t.Namespace); Type persistentInterface = GetPersistentInterface(sourceType); if (persistentInterface!=null) { if (!sourceType.GetCustomAttributes(typeof (StorageProviderAttribute)).Any()) ReportError(String.Format("No StorageProvider attribute specified for grain class {0}", sourceType.FullName)); if (!persistentInterface.IsInterface) { hasStateClass = false; return null; } else { ConsoleText.WriteError(String.Format("Warning: Usage of grain state interfaces as type arguments for Grain<T> has been deprecated. " + "Define an equivalent class with automatic properties instead of the state interface for {0}.", sourceType.FullName)); } } Dictionary<string, PropertyInfo> asyncProperties = GrainInterfaceData.GetPersistentProperties(persistentInterface) .ToDictionary(p => p.Name.Substring(p.Name.LastIndexOf('.') + 1), p => p); Dictionary<string, string> properties = asyncProperties.ToDictionary(p => p.Key, p => GetGenericTypeName(GrainInterfaceData.GetPromptType(p.Value.PropertyType), referred, nonamespace)); var stateClass = new CodeTypeDeclaration(stateClassBaseName); if (genericTypeParams != null) stateClass.TypeParameters.AddRange(genericTypeParams); stateClass.IsClass = true; if (persistentInterface != null) stateClass.TypeAttributes = persistentInterface.IsPublic ? TypeAttributes.Public : TypeAttributes.NotPublic; else stateClass.TypeAttributes = TypeAttributes.Public; stateClass.BaseTypes.Add(new CodeTypeReference(typeof(GrainState), CodeTypeReferenceOptions.GlobalReference)); MarkAsGeneratedCode(stateClass); referred(typeof(GrainState)); if (persistentInterface != null) stateClass.BaseTypes.Add( new CodeTypeReference(GetGenericTypeName(persistentInterface, referred, nonamespace))); stateClass.CustomAttributes.Add(new CodeAttributeDeclaration(typeof(SerializableAttribute).Name)); stateClass.CustomAttributes.Add(new CodeAttributeDeclaration(new CodeTypeReference(typeof(GrainStateAttribute), CodeTypeReferenceOptions.GlobalReference), new CodeAttributeArgument(new CodePrimitiveExpression(grainInterfaceData.Type.Namespace + "." + TypeUtils.GetParameterizedTemplateName(grainInterfaceData.Type, language: language))))); referred(typeof(SerializableAttribute)); referred(typeof(OnDeserializedAttribute)); var initStateFields = new CodeMemberMethod {Name = "InitStateFields"}; initStateFields.Attributes = (initStateFields.Attributes & ~MemberAttributes.AccessMask) | MemberAttributes.Private; foreach (var peoperty in asyncProperties) { Type propertyType = peoperty.Value.PropertyType; bool noCreateNew = propertyType.IsPrimitive || typeof(string).IsAssignableFrom(propertyType) // Primative types || propertyType.IsAbstract || propertyType.IsInterface || propertyType.IsGenericParameter // No concrete implementation || propertyType.GetConstructor(Type.EmptyTypes) == null; // No default constructor var initExpression = noCreateNew // Pre-initialize this type to default value ? (CodeExpression) new CodeDefaultValueExpression( new CodeTypeReference(GetGenericTypeName(propertyType, referred, nonamespace))) : new CodeObjectCreateExpression( new CodeTypeReference(GetGenericTypeName(propertyType, referred, nonamespace))); initStateFields.Statements.Add(new CodeAssignStatement( new CodePropertyReferenceExpression(new CodeThisReferenceExpression(), peoperty.Key), initExpression)); } hasStateClass = properties.Count > 0; if (hasStateClass) { foreach (var pair in properties) GenerateStateClassProperty(stateClass, asyncProperties[pair.Key], pair.Key, pair.Value); var returnType = new CodeTypeReference("System.Collections.Generic.IDictionary", new CodeTypeReference(typeof(string)), new CodeTypeReference(typeof(object))); var concreteType = new CodeTypeReference("System.Collections.Generic.Dictionary", new CodeTypeReference(typeof(string)), new CodeTypeReference(typeof(object))); var asDictionary = new CodeMemberMethod { Name = "AsDictionary", Attributes = MemberAttributes.Public | MemberAttributes.Override, ReturnType = returnType }; asDictionary.Statements.Add(new CodeVariableDeclarationStatement(concreteType, "result", new CodeObjectCreateExpression(concreteType))); foreach (var pair in properties) asDictionary.Statements.Add(new CodeAssignStatement( new CodeIndexerExpression(new CodeVariableReferenceExpression("result"), new CodePrimitiveExpression(pair.Key)), new CodePropertyReferenceExpression(new CodeThisReferenceExpression(), pair.Key))); asDictionary.Statements.Add(new CodeMethodReturnStatement(new CodeVariableReferenceExpression("result"))); stateClass.Members.Add(asDictionary); GenerateSetAll(stateClass, properties); GenerateToString(stateClass, stateClassName, properties); } // Copier, serializer, and deserializer for the state class var copier = SerializerGenerationUtilities.GenerateCopier("_Copier", stateClassName, genericTypeParams); var serializer = SerializerGenerationUtilities.GenerateSerializer("_Serializer", stateClassName, genericTypeParams); var deserializer = SerializerGenerationUtilities.GenerateDeserializer("_Deserializer", stateClassName, genericTypeParams); var ctor = new CodeConstructor { Attributes = (copier.Attributes & ~MemberAttributes.AccessMask) | MemberAttributes.Public }; ctor.BaseConstructorArgs.Add(new CodePrimitiveExpression(TypeUtils.GetFullName(grainInterfaceData.Type, language))); ctor.Statements.Add(new CodeMethodInvokeExpression( new CodeThisReferenceExpression(), "InitStateFields")); copier.Statements.Add(new CodeMethodReturnStatement( new CodeMethodInvokeExpression(new CodeVariableReferenceExpression("input"), "DeepCopy"))); serializer.Statements.Add( new CodeMethodInvokeExpression( new CodeVariableReferenceExpression("input"), "SerializeTo", new CodeArgumentReferenceExpression("stream"))); deserializer.Statements.Add(new CodeVariableDeclarationStatement(stateClassName, "result", new CodeObjectCreateExpression(stateClassName))); deserializer.Statements.Add(new CodeMethodInvokeExpression( new CodeVariableReferenceExpression("result"), "DeserializeFrom", new CodeArgumentReferenceExpression("stream"))); deserializer.Statements.Add(new CodeMethodReturnStatement( new CodeVariableReferenceExpression("result"))); stateClass.Members.Add(ctor); stateClass.Members.Add(initStateFields); stateClass.Members.Add(copier); stateClass.Members.Add(serializer); stateClass.Members.Add(deserializer); return stateClass; }
private static bool TryGetGrainClassData(GrainInterfaceData interfaceData, out GrainClassData implementation, string grainClassNamePrefix) { implementation = null; var implementations = interfaceData.Implementations; if (implementations.Length == 0) { return(false); } if (String.IsNullOrEmpty(grainClassNamePrefix)) { if (implementations.Length == 1) { implementation = implementations[0]; return(true); } if (interfaceData.PrimaryImplementation != null) { implementation = interfaceData.PrimaryImplementation; return(true); } throw new OrleansException(String.Format("Cannot resolve grain interface ID={0} to a grain class because of multiple implementations of it: {1}", interfaceData.InterfaceId, Utils.EnumerableToString(implementations, d => d.GrainClass, ",", false))); } if (implementations.Length == 1) { if (implementations[0].GrainClass.StartsWith(grainClassNamePrefix, StringComparison.Ordinal)) { implementation = implementations[0]; return(true); } return(false); } var matches = implementations.Where(impl => impl.GrainClass.Equals(grainClassNamePrefix)).ToArray(); //exact match? if (matches.Length == 0) { matches = implementations.Where( impl => impl.GrainClass.StartsWith(grainClassNamePrefix, StringComparison.Ordinal)).ToArray(); //prefix matches } if (matches.Length == 0) { return(false); } if (matches.Length == 1) { implementation = matches[0]; return(true); } throw new OrleansException(String.Format("Cannot resolve grain interface ID={0}, grainClassNamePrefix={1} to a grain class because of multiple implementations of it: {2}", interfaceData.InterfaceId, grainClassNamePrefix, Utils.EnumerableToString(matches, d => d.GrainClass, ",", false))); }
private void AddFactoryMethods(GrainInterfaceData si, CodeTypeDeclaration factoryClass) { RecordReferencedNamespaceAndAssembly(si.Type); }
internal GrainClassData(int grainTypeCode, string grainClass, bool isGeneric, GrainInterfaceData interfaceData, PlacementStrategy placement) { GrainTypeCode = grainTypeCode; GrainClass = grainClass; this.isGeneric = isGeneric; this.interfaceData = interfaceData; genericClassNames = new Dictionary <string, string>(); // TODO: initialize only for generic classes placementStrategy = placement ?? PlacementStrategy.GetDefault(); }
/// <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"); var castMethod = new CodeSnippetTypeMember(methodImpl); referenceClass.Members.Add(castMethod); }
protected override string GetInvokerImpl(GrainInterfaceData si, CodeTypeDeclaration invokerClass, Type grainType, GrainInterfaceInfo grainInterfaceInfo, bool isClient) { //No public method is implemented in this grain type for orleans messages if (grainInterfaceInfo.Interfaces.Count == 0) { return string.Format(@" Dim t = New System.Threading.Tasks.TaskCompletionSource(Of Object)() t.SetException(New NotImplementedException(""No grain interfaces for type {0}"")) Return t.Task ", TypeUtils.GetFullName(grainType, Language.VisualBasic)); } var builder = new StringBuilder(); builder.Append(@" Try "); var interfaceSwitchBody = String.Empty; foreach (int interfaceId in grainInterfaceInfo.Interfaces.Keys) { InterfaceInfo interfaceInfo = grainInterfaceInfo.Interfaces[interfaceId]; interfaceSwitchBody += GetMethodDispatchSwitchForInterface(interfaceId, interfaceInfo); } builder.AppendFormat( @"If grain Is Nothing Then : Throw New System.ArgumentNullException(""grain"") : End If Select Case interfaceId {0} Case Else {1} End Select", interfaceSwitchBody, "Throw New System.InvalidCastException(\"interfaceId=\"+interfaceId)"); builder.Append(@" Catch ex As Exception Dim t = New System.Threading.Tasks.TaskCompletionSource(Of Object)() t.SetException(ex) Return t.Task End Try"); return builder.ToString(); }
private void AddFactoryMethods(GrainInterfaceData si, CodeTypeDeclaration factoryClass) { RecordReferencedNamespaceAndAssembly(si.Type); if (GrainInterfaceData.IsGrainType(si.Type) && ShouldGenerateGetGrainMethods(si.Type)) AddGetGrainMethods(si, factoryClass); }
private static bool TryGetGrainClassData(GrainInterfaceData interfaceData, out GrainClassData implementation, string grainClassNamePrefix) { implementation = null; var implementations = interfaceData.Implementations; if (implementations.Length == 0) return false; if (String.IsNullOrEmpty(grainClassNamePrefix)) { if (implementations.Length == 1) { implementation = implementations[0]; return true; } if (interfaceData.PrimaryImplementation != null) { implementation = interfaceData.PrimaryImplementation; return true; } throw new OrleansException(String.Format("Cannot resolve grain interface ID={0} to a grain class because of multiple implementations of it: {1}", interfaceData.InterfaceId, Utils.EnumerableToString(implementations, d => d.GrainClass, ",", false))); } if (implementations.Length == 1) { if (implementations[0].GrainClass.StartsWith(grainClassNamePrefix, StringComparison.Ordinal)) { implementation = implementations[0]; return true; } return false; } var matches = implementations.Where(impl => impl.GrainClass.Equals(grainClassNamePrefix)).ToArray(); //exact match? if (matches.Length == 0) matches = implementations.Where( impl => impl.GrainClass.StartsWith(grainClassNamePrefix, StringComparison.Ordinal)).ToArray(); //prefix matches if (matches.Length == 0) return false; if (matches.Length == 1) { implementation = matches[0]; return true; } throw new OrleansException(String.Format("Cannot resolve grain interface ID={0}, grainClassNamePrefix={1} to a grain class because of multiple implementations of it: {2}", interfaceData.InterfaceId, grainClassNamePrefix, Utils.EnumerableToString(matches, d => d.GrainClass, ",", false))); }
protected virtual void AddGetGrainMethods(GrainInterfaceData iface, CodeTypeDeclaration factoryClass) { throw new NotImplementedException("GrainNamespace.AddGetGrainMethods"); }
/// <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 virtual void AddCastMethods(GrainInterfaceData si, bool isFactory, CodeTypeDeclaration referenceClass) { throw new NotImplementedException("GrainNamespace.AddCastMethods"); }
private void GetActivationNamespace(CodeNamespace factoryNamespace, GrainInterfaceData grainInterfaceData) { if (!typeof (Grain).IsAssignableFrom(grainInterfaceData.Type)) return; // generate a state class bool hasStateClass; var code = GetStateClass(grainInterfaceData, RecordReferencedNamespaceAndAssembly, grainInterfaceData.StateClassBaseName, grainInterfaceData.StateClassName, out hasStateClass); if (code != null && hasStateClass) factoryNamespace.Types.Add(code); }
protected override void AddCreateObjectReferenceMethods(GrainInterfaceData grainInterfaceData, CodeTypeDeclaration factoryClass) { throw new NotImplementedException("AddCreateObjectReferenceMethods"); }
private CodeTypeDeclaration GetInvokerClass(GrainInterfaceData si, bool isClient) { Type grainType = si.Type; CodeTypeParameterCollection genericTypeParams = si.GenericTypeParams; var invokerClass = new CodeTypeDeclaration(si.InvokerClassBaseName); if (genericTypeParams != null) invokerClass.TypeParameters.AddRange(genericTypeParams); invokerClass.IsClass = true; MarkAsGeneratedCode(invokerClass); invokerClass.BaseTypes.Add(si.IsExtension ? new CodeTypeReference(typeof (IGrainExtensionMethodInvoker), CodeTypeReferenceOptions.GlobalReference) : new CodeTypeReference(typeof (IGrainMethodInvoker), CodeTypeReferenceOptions.GlobalReference)); GrainInterfaceInfo grainInterfaceInfo = GetInterfaceInfo(grainType); var interfaceId = grainInterfaceInfo.Interfaces.Keys.First(); invokerClass.CustomAttributes.Add(new CodeAttributeDeclaration( new CodeTypeReference(typeof(MethodInvokerAttribute), CodeTypeReferenceOptions.GlobalReference), new CodeAttributeArgument(new CodePrimitiveExpression(grainType.Namespace + "." + TypeUtils.GetParameterizedTemplateName(grainType, language: language))), new CodeAttributeArgument(new CodePrimitiveExpression(interfaceId)))); var interfaceIdProperty = new CodeMemberProperty { Name = "InterfaceId", Attributes = MemberAttributes.Public | MemberAttributes.Final, Type = new CodeTypeReference(typeof (int)) }; interfaceIdProperty.GetStatements.Add(new CodeMethodReturnStatement(new CodePrimitiveExpression(interfaceId))); interfaceIdProperty.PrivateImplementationType = new CodeTypeReference(typeof(IGrainMethodInvoker), CodeTypeReferenceOptions.GlobalReference); invokerClass.Members.Add(interfaceIdProperty); //Add invoke method for Orleans message var orleansInvoker = new CodeMemberMethod { Attributes = MemberAttributes.Public | MemberAttributes.Final, Name = "Invoke", ReturnType = new CodeTypeReference(typeof (Task<object>), CodeTypeReferenceOptions.GlobalReference) }; orleansInvoker.Parameters.Add(new CodeParameterDeclarationExpression(new CodeTypeReference(typeof(IAddressable), CodeTypeReferenceOptions.GlobalReference), "grain")); orleansInvoker.Parameters.Add(new CodeParameterDeclarationExpression(typeof(int), "interfaceId")); orleansInvoker.Parameters.Add(new CodeParameterDeclarationExpression(typeof(int), "methodId")); orleansInvoker.Parameters.Add(new CodeParameterDeclarationExpression(typeof(object[]), "arguments")); orleansInvoker.PrivateImplementationType = new CodeTypeReference(typeof(IGrainMethodInvoker), CodeTypeReferenceOptions.GlobalReference); var orleansInvokerImpl = new CodeSnippetStatement(GetInvokerImpl(si, invokerClass, grainType, grainInterfaceInfo, isClient)); orleansInvoker.Statements.Add(orleansInvokerImpl); invokerClass.Members.Add(orleansInvoker); //Add TryInvoke method for Orleans message, if the type is an extension interface if (si.IsExtension) { var orleansTryInvoker = new CodeMemberMethod { Attributes = MemberAttributes.Public | MemberAttributes.Final, Name = "Invoke", ReturnType = new CodeTypeReference(typeof (Task<object>), CodeTypeReferenceOptions.GlobalReference) }; orleansTryInvoker.Parameters.Add(new CodeParameterDeclarationExpression(new CodeTypeReference(typeof(IGrainExtension), CodeTypeReferenceOptions.GlobalReference), "grain")); orleansTryInvoker.Parameters.Add(new CodeParameterDeclarationExpression(typeof(int), "interfaceId")); orleansTryInvoker.Parameters.Add(new CodeParameterDeclarationExpression(typeof(int), "methodId")); orleansTryInvoker.Parameters.Add(new CodeParameterDeclarationExpression(typeof(object[]), "arguments")); orleansTryInvoker.PrivateImplementationType = new CodeTypeReference(typeof(IGrainExtensionMethodInvoker), CodeTypeReferenceOptions.GlobalReference); var orleansTryInvokerImp = new CodeSnippetStatement(GetInvokerImpl(si, invokerClass, grainType, grainInterfaceInfo, isClient)); orleansTryInvoker.Statements.Add(orleansTryInvokerImp); invokerClass.Members.Add(orleansTryInvoker); } //Add GetMethodName() method var getMethodName = new CodeMemberMethod { Attributes = MemberAttributes.Public | MemberAttributes.Final | MemberAttributes.Static, Name = "GetMethodName", ReturnType = new CodeTypeReference(typeof (string)) }; getMethodName.Parameters.Add(new CodeParameterDeclarationExpression(typeof(int), "interfaceId")); getMethodName.Parameters.Add(new CodeParameterDeclarationExpression(typeof(int), "methodId")); var orleansGetMethodNameImpl = new CodeSnippetStatement(GetOrleansGetMethodNameImpl(grainType, grainInterfaceInfo)); getMethodName.Statements.Add(orleansGetMethodNameImpl); invokerClass.Members.Add(getMethodName); return invokerClass; }
protected override void AddGetGrainMethods(GrainInterfaceData iface, CodeTypeDeclaration factoryClass) { throw new NotImplementedException("AddGetGrainMethods"); }
internal void AddStateClass(GrainInterfaceData interfaceData) { GetActivationNamespace(ReferencedNamespace, interfaceData); }
/// <summary> /// Read a grain assembly and extract codegen info for each Orleans grain / service interface /// </summary> /// <param name="inputAssembly">Input grain assembly</param> /// <param name="namespaceDictionary">output list of grain namespace</param> /// <param name="outputAssemblyName">Output assembly being generated</param> /// <param name="options">Code generation options</param> internal bool ProcessInputAssembly( Assembly inputAssembly, Dictionary<string, NamespaceGenerator> namespaceDictionary, string outputAssemblyName, CodeGenOptions options) { if(!Debugger.IsAttached) ReferenceResolver.AssertUniqueLoadForEachAssembly(); var processedGrainTypes = new List<string>(); bool success = true; ConsoleText.WriteStatus("Orleans-CodeGen - Adding grain namespaces from input Assembly " + inputAssembly.GetName()); foreach (var type in inputAssembly.GetTypes()) { if (!type.IsNested && !type.IsGenericParameter && type.IsSerializable) SerializerGenerationManager.RecordTypeToGenerate(type); if (!options.ServerGen && GrainInterfaceData.IsGrainInterface(type)) { NamespaceGenerator grainNamespace = RegisterNamespace(inputAssembly, namespaceDictionary, type, options.TargetLanguage.Value); processedGrainTypes.Add(type.FullName); try { var grainInterfaceData = new GrainInterfaceData(options.TargetLanguage.Value, type); grainNamespace.AddReferenceClass(grainInterfaceData); } catch (GrainInterfaceData.RulesViolationException rve) { foreach (var v in rve.Violations) NamespaceGenerator.ReportError(v); success = false; } } if (options.ServerGen && !type.IsAbstract && (GrainInterfaceData.IsAddressable(type))) { var grainNamespace = RegisterNamespace(inputAssembly, namespaceDictionary, type, options.TargetLanguage.Value); try { var grainInterfaceData = GrainInterfaceData.FromGrainClass(type, options.TargetLanguage.Value); } catch (GrainInterfaceData.RulesViolationException rve) { //Note: I have a separate try/catch here since we are issuing warnings instead of compile error unlike the Grain Interface validations above. //Question: Should we instead throw compile errors? //Question: What warning number should we use? Standard C# warning/error numbers are listed here: https://msdn.microsoft.com/en-us/library/ms228296(v=vs.90).aspx foreach (var v in rve.Violations) NamespaceGenerator.ReportWarning(string.Format("CS0184 : {0}", v)); } } } if (!success) return false; ConsoleText.WriteStatus("Orleans-CodeGen - Processed grain classes: "); foreach (string name in processedGrainTypes) ConsoleText.WriteStatus("\t" + name); // Generate serializers for types we encountered along the way SerializerGenerationManager.GenerateSerializers(inputAssembly, namespaceDictionary, outputAssemblyName, options.TargetLanguage.Value); return true; }
private static bool ShouldGenerateObjectRefFactory(GrainInterfaceData ifaceData) { var ifaceType = ifaceData.Type; // generate CreateObjectReference in 2 cases: // 1) for interfaces derived from IGrainObserver // 2) when specifically specifies via FactoryTypes.ClientObject or FactoryTypes.Both if(IsObserver(ifaceType)) return true; var factoryType = FactoryAttribute.CollectFactoryTypesSpecified(ifaceType); return factoryType == FactoryAttribute.FactoryTypes.ClientObject || factoryType == FactoryAttribute.FactoryTypes.Both; }
protected override string GetInvokerImpl( GrainInterfaceData si, CodeTypeDeclaration invokerClass, Type grainType, GrainInterfaceInfo grainInterfaceInfo, bool isClient) { //No public method is implemented in this grain type for orleans messages if (grainInterfaceInfo.Interfaces.Count == 0) { return string.Format(@" var t = new System.Threading.Tasks.TaskCompletionSource<object>(); t.SetException(new NotImplementedException(""No grain interfaces for type {0}"")); return t.Task; ", TypeUtils.GetFullName(grainType, Language.CSharp)); } var builder = new StringBuilder(); builder.AppendFormat(@" try {{"); var interfaceSwitchBody = String.Empty; foreach (int interfaceId in grainInterfaceInfo.Interfaces.Keys) { InterfaceInfo interfaceInfo = grainInterfaceInfo.Interfaces[interfaceId]; interfaceSwitchBody += GetMethodDispatchSwitchForInterface(interfaceId, interfaceInfo); } builder.AppendFormat( @" if (grain == null) throw new System.ArgumentNullException(""grain""); switch (interfaceId) {{ {0} default: {1}; }}", interfaceSwitchBody, "throw new System.InvalidCastException(\"interfaceId=\"+interfaceId)"); builder.AppendFormat(@" }} catch(Exception ex) {{ var t = new System.Threading.Tasks.TaskCompletionSource<object>(); t.SetException(ex); return t.Task; }}"); return builder.ToString(); }
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, language: language))))); 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.Public | 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); }
/// <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"); var castMethod = new CodeSnippetTypeMember(methodImpl); referenceClass.Members.Add(castMethod); }
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)))); 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( @" Public Shared Function GetGrain(primaryKey as System.Int64, keyExt as System.String) As {0} Return Cast(Global.Orleans.CodeGeneration.GrainFactoryBase.MakeKeyExtendedGrainReferenceInternal(GetType({0}), 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}), primaryKey, keyExt, grainClassNamePrefix)) End Function"); } else if (isGuidCompoundKey) { add( @" Public Shared Function GetGrain(primaryKey As System.Guid, keyExt as System.String) As {0} Return Cast(Global.Orleans.CodeGeneration.GrainFactoryBase.MakeKeyExtendedGrainReferenceInternal(GetType({0}), 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}), 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}), 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}), 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}), 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}), 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}), 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}), primaryKey, grainClassNamePrefix)) End Function"); } } }