private static MethodDeclarationSyntax GenerateOnActivateAsyncMethod(int readReplicaCount) { return(RoslynUtils.ParseMethod(string.Format( @" public override async Task OnActivateAsync() {{ _topology = SwmrUtils.CreateTopology(this.GetPrimaryKeyString(), {0}); await base.OnActivateAsync(); }}", readReplicaCount))); }
public MethodDeclarationSyntax GenerateSetStateMethod(string grainStateTypeName) { return(RoslynUtils.ParseMethod(string.Format( @" public Task SetState(GrainState state) {{ State = state as {0}; return TaskDone.Done; }}", grainStateTypeName))); }
private static MethodDeclarationSyntax GenerateReadReplicaOnActivateAsync(ITypeSymbol swmrInterface) { return(RoslynUtils.ParseMethod(string.Format( @" public override async Task OnActivateAsync() {{ string grainId = SwmrUtils.GetGrainId(this.GetPrimaryKeyString()); {0} grain = GrainFactory.GetGrain<{0}>(grainId); await SetState(await grain.GetState()); await base.OnActivateAsync(); }}", swmrInterface.Name))); }
private static ClassDeclarationSyntax GenerateReadGrain(ClassDeclarationSyntax grainClass, ITypeSymbol swmrInterface, int readReplicaCount) { string readGrainName = SwmrUtils.GetReadInterfaceName(grainClass.Identifier.Text); string readerInterfaceName = SwmrUtils.GetReadInterfaceName(swmrInterface.Name); ClassDeclarationSyntax readGrain = GenerateClassSqueleton(readGrainName).WithAttributeLists(AttributeUtils.AttributeListList(AttributeUtils.Attribute(StatelessWorkerAttributeName))).WithBaseList(RoslynUtils.BaseList(new[] { "Grain", readerInterfaceName })); readGrain = RoslynUtils.AddField(readGrain, "ITopology<string>", "_topology"); readGrain = readGrain.AddMembers(GenerateOnActivateAsyncMethod(readReplicaCount)); string readReplicaInterfaceName = SwmrUtils.GetReadReplicaInterfaceName(swmrInterface.Name); foreach (ISymbol member in swmrInterface.GetMembers()) { IMethodSymbol methodSymbol = member as IMethodSymbol; if (methodSymbol == null || !IsReadOnlyMethod(methodSymbol)) { continue; } MethodInspector methodInspector = new MethodInspector(methodSymbol); string parameters = "string sessionId"; if (methodInspector.MethodParams.Any()) { parameters = string.Join(", ", methodInspector.MethodParams.Select(param => string.Format("{0} {1}", param.Value, param.Key))) + " ," + parameters; } var method = RoslynUtils.ParseMethod(string.Format( @" public {0} {1}({2}) {{ string sessionNode = _topology.GetNode(sessionId); var readReplica = GrainFactory.GetGrain<{3}>(sessionNode); return readReplica.{1}({4}); }}", methodInspector.ReturnType, methodInspector.MethodName, parameters, readReplicaInterfaceName, string.Join(", ", methodInspector.MethodParams.Keys))); readGrain = readGrain.AddMembers( method.WithLeadingTrivia(SF.EndOfLine(""))); } return(readGrain); }
private static ClassDeclarationSyntax GenerateApiControllerForInterface(InterfaceDeclarationSyntax interfaceNode, SemanticModel semanticModel) { if (!RoslynUtils.IsPublic(interfaceNode)) { return(null); } AttributeSyntax apiControllerAttribute = AttributeUtils.SelectAttributeOfType(interfaceNode.AttributeLists, typeof(ApiControllerAttribute), semanticModel); // if the interface is not annotated with the ApiController attribute, do nothing if (apiControllerAttribute == null) { return(null); } var namespaceNode = interfaceNode.Parent as NamespaceDeclarationSyntax; if (namespaceNode == null) { throw new Exception("A grain interface must be declared inside a namespace"); } // copy all attributes except the ApiController attribute SyntaxList <AttributeListSyntax> attributesLists = AttributeUtils.RemoveAttributeOfType(interfaceNode.AttributeLists, typeof(ApiControllerAttribute), semanticModel); // add the RoutePrefix attribute (if any) var attributeInspector = new AttributeInspector(apiControllerAttribute, semanticModel); if (attributeInspector.NamedArguments.ContainsKey(RoutePrefix)) { AttributeSyntax routePrefixAttribute = AttributeUtils.AttributeWithArgument(RoutePrefix, attributeInspector.NamedArguments[RoutePrefix]); attributesLists = attributesLists.Add(AttributeUtils.AttributeList(routePrefixAttribute)); } string grainName = interfaceNode.Identifier.Text; string apiControllerName = GetApiControllerName(grainName); // create the Api controller class, add the attributes to it and make it a subclass of ApiController ClassDeclarationSyntax classDclr = SF.ClassDeclaration(SF.Identifier(apiControllerName)).AddModifiers(SF.Token(SyntaxKind.PublicKeyword), SF.Token(SyntaxKind.PartialKeyword)).WithAttributeLists(SF.List(attributesLists)).WithBaseList(SF.BaseList(SF.SeparatedList <BaseTypeSyntax>().Add(SF.SimpleBaseType(SF.IdentifierName(ApicontrollerClassName))))); // Add the IGrainFactory field and to the constructor classDclr = RoslynUtils.AddField(classDclr, "IGrainFactory", "_grainFactory"); MethodDeclarationSyntax constructor = RoslynUtils.ParseMethod(string.Format(@" public {0}(IGrainFactory grainFactory) {{ _grainFactory = grainFactory; }}", apiControllerName)).WithTrailingTrivia(SF.EndOfLine("")); classDclr = classDclr.AddMembers(constructor); // generate the api controller methods and add them to the class IEnumerable <MethodDeclarationSyntax> apiControllerMethods = GenerateApiControllerMethods(RoslynUtils.GetMethodDeclarations(interfaceNode), grainName); // ReSharper disable once LoopCanBeConvertedToQuery foreach (var method in apiControllerMethods) { classDclr = classDclr.AddMembers(method); } return(classDclr); }