diff --git a/components/AppServices/CommunityToolkit.AppServices.SourceGenerators/AnalyzerReleases.Shipped.md b/components/AppServices/CommunityToolkit.AppServices.SourceGenerators/AnalyzerReleases.Shipped.md
new file mode 100644
index 000000000..d846c9b2d
--- /dev/null
+++ b/components/AppServices/CommunityToolkit.AppServices.SourceGenerators/AnalyzerReleases.Shipped.md
@@ -0,0 +1,16 @@
+; Shipped analyzer releases
+; https://github.com/dotnet/roslyn-analyzers/blob/main/src/Microsoft.CodeAnalysis.Analyzers/ReleaseTrackingAnalyzers.Help.md
+
+## Release 1.0
+
+### New Rules
+
+Rule ID | Category | Severity | Notes
+--------|----------|----------|-------
+APPSRVSPR0001 | CommunityToolkit.AppServices.SourceGenerators.InvalidAppServicesMemberAnalyzer | Error |
+APPSRVSPR0002 | CommunityToolkit.AppServices.SourceGenerators.InvalidAppServicesMemberAnalyzer | Error |
+APPSRVSPR0003 | CommunityToolkit.AppServices.SourceGenerators.InvalidAppServicesMemberAnalyzer | Error |
+APPSRVSPR0004 | CommunityToolkit.AppServices.SourceGenerators.InvalidAppServicesMemberAnalyzer | Error |
+APPSRVSPR0005 | CommunityToolkit.AppServices.SourceGenerators.InvalidAppServicesMemberAnalyzer | Error |
+APPSRVSPR0006 | CommunityToolkit.AppServices.SourceGenerators.InvalidValueSetSerializerUseAnalyzer | Error |
+APPSRVSPR0007 | CommunityToolkit.AppServices.SourceGenerators.InvalidValueSetSerializerUseAnalyzer | Warning |
diff --git a/components/AppServices/CommunityToolkit.AppServices.SourceGenerators/AnalyzerReleases.Unshipped.md b/components/AppServices/CommunityToolkit.AppServices.SourceGenerators/AnalyzerReleases.Unshipped.md
new file mode 100644
index 000000000..f2b7fad65
--- /dev/null
+++ b/components/AppServices/CommunityToolkit.AppServices.SourceGenerators/AnalyzerReleases.Unshipped.md
@@ -0,0 +1,2 @@
+; Unshipped analyzer release
+; https://github.com/dotnet/roslyn-analyzers/blob/main/src/Microsoft.CodeAnalysis.Analyzers/ReleaseTrackingAnalyzers.Help.md
diff --git a/components/AppServices/CommunityToolkit.AppServices.SourceGenerators/AppServiceGenerator.Component.cs b/components/AppServices/CommunityToolkit.AppServices.SourceGenerators/AppServiceGenerator.Component.cs
new file mode 100644
index 000000000..edae6e6c2
--- /dev/null
+++ b/components/AppServices/CommunityToolkit.AppServices.SourceGenerators/AppServiceGenerator.Component.cs
@@ -0,0 +1,276 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System.Threading;
+using Microsoft.CodeAnalysis;
+using Microsoft.CodeAnalysis.CSharp;
+using Microsoft.CodeAnalysis.CSharp.Syntax;
+using CommunityToolkit.AppServices.SourceGenerators.Extensions;
+using CommunityToolkit.AppServices.SourceGenerators.Helpers;
+using CommunityToolkit.AppServices.SourceGenerators.Models;
+using static Microsoft.CodeAnalysis.CSharp.SyntaxFactory;
+
+namespace CommunityToolkit.AppServices.SourceGenerators;
+
+///
+partial class AppServiceGenerator : IIncrementalGenerator
+{
+ ///
+ /// Generator logic for app service components.
+ ///
+ private static class Component
+ {
+ ///
+ /// Gathers info on a component.
+ ///
+ /// The input instance to inspect.
+ /// The cancellation token for the operation.
+ /// The interface type and service name, or .
+ public static (INamedTypeSymbol? ServiceSymbol, string? ServiceName) GetInfo(INamedTypeSymbol symbol, CancellationToken token)
+ {
+ foreach (INamedTypeSymbol interfaceSymbol in symbol.Interfaces)
+ {
+ token.ThrowIfCancellationRequested();
+
+ if (interfaceSymbol.TryGetAppServicesNameFromAttribute(out string? serviceName))
+ {
+ return (interfaceSymbol, serviceName);
+ }
+ }
+
+ return default;
+ }
+
+ ///
+ /// Gets a registering all available service endpoints.
+ ///
+ /// The input hierarchy for the component.
+ /// The app service info.
+ /// The for the component.
+ public static ConstructorDeclarationSyntax GetSyntax(HierarchyInfo hierarchy, AppServiceInfo info)
+ {
+ using ImmutableArrayBuilder registrationStatements = ImmutableArrayBuilder.Rent();
+
+ // Prepare the endpoint registrations
+ foreach (MethodInfo methodInfo in info.Methods)
+ {
+ if (methodInfo.Parameters.IsEmpty)
+ {
+ using ImmutableArrayBuilder endpointArguments = ImmutableArrayBuilder.Rent();
+
+ if (methodInfo.HasCustomValueSetSerializer)
+ {
+ // This adds the serializer expression:
+ //
+ // new ()
+ endpointArguments.Add(Argument(ObjectCreationExpression(IdentifierName(methodInfo.FullyQualifiedValueSetSerializerTypeName)).AddArgumentListArguments()));
+ }
+
+ // Add the common arguments:
+ //
+ // , ""
+ endpointArguments.Add(Argument(MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression, ThisExpression(), IdentifierName(methodInfo.MethodName))));
+ endpointArguments.Add(Argument(LiteralExpression(SyntaxKind.StringLiteralExpression, Literal(methodInfo.MethodName))));
+
+ // This creates a registration for a parameterless endpoint:
+ //
+ // base.RegisterEndpoint();
+ registrationStatements.Add(
+ ExpressionStatement(
+ InvocationExpression(
+ MemberAccessExpression(
+ SyntaxKind.SimpleMemberAccessExpression,
+ BaseExpression(),
+ IdentifierName("RegisterEndpoint")))
+ .AddArgumentListArguments(endpointArguments.ToArray())));
+ }
+ else
+ {
+ using ImmutableArrayBuilder endpointStatements = ImmutableArrayBuilder.Rent();
+ using ImmutableArrayBuilder endpointArguments = ImmutableArrayBuilder.Rent();
+
+ foreach (ParameterInfo parameterInfo in methodInfo.Parameters)
+ {
+ if (parameterInfo.Type.HasFlag(ParameterOrReturnType.IProgressOfT))
+ {
+ using ImmutableArrayBuilder progressArguments = ImmutableArrayBuilder.Rent();
+
+ if (parameterInfo.HasCustomValueSetSerializer)
+ {
+ // This adds the serializer expression, like above:
+ //
+ // new ()
+ progressArguments.Add(Argument(ObjectCreationExpression(IdentifierName(parameterInfo.FullyQualifiedValueSetSerializerTypeName)).AddArgumentListArguments()));
+ }
+
+ // Add the common argument:
+ //
+ // out