/// <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; }