Esempio n. 1
0
        /// <summary>
        /// Returns the description of the provided actor type.
        /// </summary>
        /// <param name="type">
        /// The actor type.
        /// </param>
        /// <returns>
        /// The description of the provided actor type.
        /// </returns>
        private static ActorDescription GetActorDescription(Type type)
        {
            var actorAttr = type.GetCustomAttribute <ActorAttribute>() ?? new ActorAttribute(type);
            var result    = new ActorDescription
            {
                Kind        = actorAttr.Kind,
                IsSingleton = actorAttr.IsSingleton,
                Methods     = new Dictionary <string, ActorMethodDescription>(),
                Type        = type
            };

            // Get all server-visible methods from the type.
            var methods = type.GetInterfaces().SelectMany(iface => iface.GetMethods()).Concat(type.GetMethods());

            foreach (var method in methods)
            {
                var methodDescription = GetMethodDescription(method);
                var ev   = method.GetCustomAttribute <EventAttribute>();
                var name = ev != null ? ev.Type : ProxyGenerationUtility.ToCanonicalName(method.Name);

                result.Methods[name] = methodDescription;
            }

            return(result);
        }
 /// <summary>
 /// Returns syntax for dispatching <paramref name="event"/> to <paramref name="actor"/>.
 /// </summary>
 /// <param name="actor">
 /// The actor description.
 /// </param>
 /// <param name="event">
 /// The event.
 /// </param>
 /// <returns>
 /// Syntax for dispatching <paramref name="event"/> to <paramref name="actor"/>.
 /// </returns>
 private static SwitchSectionSyntax GetActorSwitch(
     ActorDescription actor, 
     ExpressionSyntax @event)
 {
     var label =
         SF.CaseSwitchLabel(SF.LiteralExpression(SyntaxKind.StringLiteralExpression, SF.Literal(actor.Kind)));
     return
         SF.SwitchSection()
             .AddLabels(label)
             .AddStatements(GenerateActorBlock(@event, actor));
 }
        /// <summary>
        /// Returns syntax for dispatching <paramref name="event"/> to <paramref name="actor"/>.
        /// </summary>
        /// <param name="event">
        /// The event.
        /// </param>
        /// <param name="actor">
        /// The actor description.
        /// </param>
        /// <returns>
        /// Syntax for dispatching <paramref name="event"/> to <paramref name="actor"/>.
        /// </returns>
        private static StatementSyntax GenerateActorBlock(
            ExpressionSyntax @event, 
            ActorDescription actor)
        {
            var @var = SF.IdentifierName("var");
            var grainType = actor.Type.GetTypeSyntax();
            var getGrain =
                SF.InvocationExpression(SF.IdentifierName("GrainFactory").Member("GetGrain", grainType))
                    .AddArgumentListArguments(SF.Argument(@event.Member("To").Member("Id")));
            var grain = SF.VariableDeclarator("grain").WithInitializer(SF.EqualsValueClause(getGrain));
            var grainDeclaration = SF.LocalDeclarationStatement(SF.VariableDeclaration(@var).AddVariables(grain));

            var returnNull = SF.ReturnStatement(SF.LiteralExpression(SyntaxKind.NullLiteralExpression));

            var defaultSection = SF.SwitchSection().AddLabels(SF.DefaultSwitchLabel()).AddStatements(returnNull);
            var methodSwitch =
                SF.SwitchStatement(@event.Member("Type"))
                    .AddSections(
                        actor.Methods.Values.Where(_ => _.Visible)
                            .Select(method => GetMethodSwitchCase(@event, method))
                            .ToArray())
                    .AddSections(defaultSection);
            var methodDispatcher = SF.Block().AddStatements(grainDeclaration, methodSwitch);
            return methodDispatcher;
        }