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);
        }
        private ClassDeclarationSyntax GenerateReadReplicaGrain(ClassDeclarationSyntax grainClass, ITypeSymbol swmrInterface)
        {
            string readReplicaGrainName             = SwmrUtils.GetReadReplicaGrainName(grainClass.Identifier.Text);
            string readReplicaInterfaceName         = SwmrUtils.GetReadReplicaInterfaceName(swmrInterface.Name);
            ClassDeclarationSyntax readReplicaGrain = GenerateClassSqueleton(readReplicaGrainName).WithBaseList(RoslynUtils.BaseList(new[] { "Grain", readReplicaInterfaceName }));

            string grainStateTypeName = FindGrainStateTypeName(grainClass);

            readReplicaGrain = readReplicaGrain.AddMembers(SF.FieldDeclaration(SF.VariableDeclaration(SF.ParseTypeName(grainStateTypeName), SF.SeparatedList(new[] { SF.VariableDeclarator(SF.Identifier("State")) }))).AddModifiers(SF.Token(SyntaxKind.PrivateKeyword)));

            readReplicaGrain = readReplicaGrain.AddMembers(GenerateReadReplicaOnActivateAsync(swmrInterface));

            foreach (ISymbol member in swmrInterface.GetMembers())
            {
                IMethodSymbol methodSymbol = member as IMethodSymbol;
                if (methodSymbol == null || !IsReadOnlyMethod(methodSymbol))
                {
                    continue;
                }
                MethodDeclarationSyntax methodImpl = RoslynUtils.FindImplementation(methodSymbol, grainClass);
                readReplicaGrain = readReplicaGrain.AddMembers(methodImpl.WithLeadingTrivia(SF.EndOfLine("")));
            }

            readReplicaGrain = readReplicaGrain.AddMembers(GenerateSetStateMethod(grainStateTypeName));

            return(readReplicaGrain);
        }
示例#4
0
        private static InterfaceDeclarationSyntax GenerateInterface(string name, IEnumerable <MethodDeclarationSyntax> methods, BaseListSyntax baseList)
        {
            InterfaceDeclarationSyntax generatedInterface = SF.InterfaceDeclaration(name).AddModifiers(SF.Token(SyntaxKind.PublicKeyword)).WithBaseList(baseList);

            foreach (var method in methods)
            {
                generatedInterface = generatedInterface.AddMembers(method.WithLeadingTrivia(SF.EndOfLine("")));
            }
            return(generatedInterface);
        }