@@ -63,10 +63,13 @@ public void Execute(GeneratorExecutionContext context)
6363
6464 foreach ( INamedTypeSymbol classSymbol in syntaxReceiver . GatheredInfo )
6565 {
66- // Create a static method to register all messages for a given recipient type.
66+ // Create a static factory method to register all messages for a given recipient type.
67+ // This follows the same pattern used in ObservableValidatorValidateAllPropertiesGenerator,
68+ // with the same advantages mentioned there (type safety, more AOT-friendly, etc.).
6769 // There are two versions that are generated: a non-generic one doing the registration
6870 // with no tokens, which is the most common scenario and will help particularly in AOT
6971 // scenarios, and a generic version that will support all other cases with custom tokens.
72+ // Note: the generic overload has a different name to simplify the lookup with reflection.
7073 // This code takes a class symbol and produces a compilation unit as follows:
7174 //
7275 // // Licensed to the .NET Foundation under one or more agreements.
@@ -86,17 +89,27 @@ public void Execute(GeneratorExecutionContext context)
8689 // {
8790 // [global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)]
8891 // [global::System.Obsolete("This method is not intended to be called directly by user code")]
89- // public static void RegisterAll( IMessenger messenger, <RECIPIENT_TYPE> recipient )
92+ // public static global::System.Action< IMessenger, object> CreateAllMessagesRegistrator( <RECIPIENT_TYPE> _ )
9093 // {
91- // <BODY>
94+ // static void RegisterAll(IMessenger messenger, <INSTANCE_TYPE> instance)
95+ // {
96+ // <BODY>
97+ // }
98+ //
99+ // return static (m, r) => RegisterAll(m, (<INSTANCE_TYPE>)r);
92100 // }
93101 //
94102 // [global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)]
95103 // [global::System.Obsolete("This method is not intended to be called directly by user code")]
96- // public static void RegisterAll<TToken>( IMessenger messenger, < RECIPIENT_TYPE> recipient, TToken token )
104+ // public static global::System.Action< IMessenger, object, TToken> CreateAllMessagesRegistratorWithToken<TToken>(< RECIPIENT_TYPE> _ )
97105 // where TToken : global::System.IEquatable<TToken>
98106 // {
99- // <BODY>
107+ // static void RegisterAll(IMessenger messenger, <INSTANCE_TYPE> instance, TToken token)
108+ // {
109+ // <BODY>
110+ // }
111+ //
112+ // return static (m, r, t) => RegisterAll(m, (<INSTANCE_TYPE>)r, t);
100113 // }
101114 // }
102115 // }
@@ -112,8 +125,10 @@ public void Execute(GeneratorExecutionContext context)
112125 Token ( SyntaxKind . StaticKeyword ) ,
113126 Token ( SyntaxKind . PartialKeyword ) ) . AddAttributeLists ( classAttributes ) . AddMembers (
114127 MethodDeclaration (
115- PredefinedType ( Token ( SyntaxKind . VoidKeyword ) ) ,
116- Identifier ( "RegisterAll" ) ) . AddAttributeLists (
128+ GenericName ( "global::System.Action" ) . AddTypeArgumentListArguments (
129+ IdentifierName ( "IMessenger" ) ,
130+ PredefinedType ( Token ( SyntaxKind . ObjectKeyword ) ) ) ,
131+ Identifier ( "CreateAllMessagesRegistrator" ) ) . AddAttributeLists (
117132 AttributeList ( SingletonSeparatedList (
118133 Attribute ( IdentifierName ( "global::System.ComponentModel.EditorBrowsable" ) ) . AddArgumentListArguments (
119134 AttributeArgument ( ParseExpression ( "global::System.ComponentModel.EditorBrowsableState.Never" ) ) ) ) ) ,
@@ -124,12 +139,35 @@ public void Execute(GeneratorExecutionContext context)
124139 Literal ( "This method is not intended to be called directly by user code" ) ) ) ) ) ) ) . AddModifiers (
125140 Token ( SyntaxKind . PublicKeyword ) ,
126141 Token ( SyntaxKind . StaticKeyword ) ) . AddParameterListParameters (
127- Parameter ( Identifier ( "messenger" ) ) . WithType ( IdentifierName ( "IMessenger" ) ) ,
128- Parameter ( Identifier ( "recipient" ) ) . WithType ( IdentifierName ( classSymbol . ToDisplayString ( SymbolDisplayFormat . FullyQualifiedFormat ) ) ) )
129- . WithBody ( Block ( EnumerateRegistrationStatements ( classSymbol , iRecipientSymbol ) . ToArray ( ) ) ) ,
142+ Parameter ( Identifier ( "_" ) ) . WithType ( IdentifierName ( classSymbol . ToDisplayString ( SymbolDisplayFormat . FullyQualifiedFormat ) ) ) )
143+ . WithBody ( Block (
144+ LocalFunctionStatement (
145+ PredefinedType ( Token ( SyntaxKind . VoidKeyword ) ) ,
146+ Identifier ( "RegisterAll" ) )
147+ . AddModifiers ( Token ( SyntaxKind . StaticKeyword ) )
148+ . AddParameterListParameters (
149+ Parameter ( Identifier ( "messenger" ) ) . WithType ( IdentifierName ( "IMessenger" ) ) ,
150+ Parameter ( Identifier ( "recipient" ) ) . WithType ( IdentifierName ( classSymbol . ToDisplayString ( SymbolDisplayFormat . FullyQualifiedFormat ) ) ) )
151+ . WithBody ( Block ( EnumerateRegistrationStatements ( classSymbol , iRecipientSymbol ) . ToArray ( ) ) ) ,
152+ ReturnStatement (
153+ ParenthesizedLambdaExpression ( )
154+ . AddModifiers ( Token ( SyntaxKind . StaticKeyword ) )
155+ . AddParameterListParameters (
156+ Parameter ( Identifier ( "m" ) ) ,
157+ Parameter ( Identifier ( "r" ) ) )
158+ . WithExpressionBody (
159+ InvocationExpression ( IdentifierName ( "RegisterAll" ) )
160+ . AddArgumentListArguments (
161+ Argument ( IdentifierName ( "m" ) ) ,
162+ Argument ( CastExpression (
163+ IdentifierName ( classSymbol . ToDisplayString ( SymbolDisplayFormat . FullyQualifiedFormat ) ) ,
164+ IdentifierName ( "r" ) ) ) ) ) ) ) ) ,
130165 MethodDeclaration (
131- PredefinedType ( Token ( SyntaxKind . VoidKeyword ) ) ,
132- Identifier ( "RegisterAll" ) ) . AddAttributeLists (
166+ GenericName ( "global::System.Action" ) . AddTypeArgumentListArguments (
167+ IdentifierName ( "IMessenger" ) ,
168+ PredefinedType ( Token ( SyntaxKind . ObjectKeyword ) ) ,
169+ IdentifierName ( "TToken" ) ) ,
170+ Identifier ( "CreateAllMessagesRegistratorWithToken" ) ) . AddAttributeLists (
133171 AttributeList ( SingletonSeparatedList (
134172 Attribute ( IdentifierName ( "global::System.ComponentModel.EditorBrowsable" ) ) . AddArgumentListArguments (
135173 AttributeArgument ( ParseExpression ( "global::System.ComponentModel.EditorBrowsableState.Never" ) ) ) ) ) ,
@@ -140,14 +178,36 @@ public void Execute(GeneratorExecutionContext context)
140178 Literal ( "This method is not intended to be called directly by user code" ) ) ) ) ) ) ) . AddModifiers (
141179 Token ( SyntaxKind . PublicKeyword ) ,
142180 Token ( SyntaxKind . StaticKeyword ) ) . AddParameterListParameters (
143- Parameter ( Identifier ( "messenger" ) ) . WithType ( IdentifierName ( "IMessenger" ) ) ,
144- Parameter ( Identifier ( "recipient" ) ) . WithType ( IdentifierName ( classSymbol . ToDisplayString ( SymbolDisplayFormat . FullyQualifiedFormat ) ) ) ,
145- Parameter ( Identifier ( "token" ) ) . WithType ( IdentifierName ( "TToken" ) ) )
181+ Parameter ( Identifier ( "_" ) ) . WithType ( IdentifierName ( classSymbol . ToDisplayString ( SymbolDisplayFormat . FullyQualifiedFormat ) ) ) )
146182 . AddTypeParameterListParameters ( TypeParameter ( "TToken" ) )
147183 . AddConstraintClauses (
148184 TypeParameterConstraintClause ( "TToken" )
149185 . AddConstraints ( TypeConstraint ( GenericName ( "global::System.IEquatable" ) . AddTypeArgumentListArguments ( IdentifierName ( "TToken" ) ) ) ) )
150- . WithBody ( Block ( EnumerateRegistrationStatementsWithTokens ( classSymbol , iRecipientSymbol ) . ToArray ( ) ) ) ) ) )
186+ . WithBody ( Block (
187+ LocalFunctionStatement (
188+ PredefinedType ( Token ( SyntaxKind . VoidKeyword ) ) ,
189+ Identifier ( "RegisterAll" ) )
190+ . AddModifiers ( Token ( SyntaxKind . StaticKeyword ) )
191+ . AddParameterListParameters (
192+ Parameter ( Identifier ( "messenger" ) ) . WithType ( IdentifierName ( "IMessenger" ) ) ,
193+ Parameter ( Identifier ( "recipient" ) ) . WithType ( IdentifierName ( classSymbol . ToDisplayString ( SymbolDisplayFormat . FullyQualifiedFormat ) ) ) ,
194+ Parameter ( Identifier ( "token" ) ) . WithType ( IdentifierName ( "TToken" ) ) )
195+ . WithBody ( Block ( EnumerateRegistrationStatementsWithTokens ( classSymbol , iRecipientSymbol ) . ToArray ( ) ) ) ,
196+ ReturnStatement (
197+ ParenthesizedLambdaExpression ( )
198+ . AddModifiers ( Token ( SyntaxKind . StaticKeyword ) )
199+ . AddParameterListParameters (
200+ Parameter ( Identifier ( "m" ) ) ,
201+ Parameter ( Identifier ( "r" ) ) ,
202+ Parameter ( Identifier ( "t" ) ) )
203+ . WithExpressionBody (
204+ InvocationExpression ( IdentifierName ( "RegisterAll" ) )
205+ . AddArgumentListArguments (
206+ Argument ( IdentifierName ( "m" ) ) ,
207+ Argument ( CastExpression (
208+ IdentifierName ( classSymbol . ToDisplayString ( SymbolDisplayFormat . FullyQualifiedFormat ) ) ,
209+ IdentifierName ( "r" ) ) ) ,
210+ Argument ( IdentifierName ( "t" ) ) ) ) ) ) ) ) ) )
151211 . NormalizeWhitespace ( )
152212 . ToFullString ( ) ;
153213
0 commit comments