#nullable enable using System; using System.Linq; using System.Reflection; using Microsoft.Extensions.DependencyInjection; using Svrnty.CQRS.Configuration; namespace Svrnty.CQRS.Grpc; /// /// Extension methods for CqrsBuilder to add gRPC support /// public static class CqrsBuilderExtensions { /// /// Adds gRPC support to the CQRS pipeline /// /// The CQRS builder /// Optional configuration for gRPC endpoints /// The CQRS builder for method chaining public static CqrsBuilder AddGrpc(this CqrsBuilder builder, Action? configure = null) { var options = new GrpcCqrsOptions(); configure?.Invoke(options); builder.Configuration.SetConfiguration(options); // Try to find and call the generated AddGrpcFromConfiguration method var addGrpcMethod = FindExtensionMethod("AddGrpcFromConfiguration"); if (addGrpcMethod != null) { addGrpcMethod.Invoke(null, new object[] { builder.Services }); } else { Console.WriteLine("Warning: AddGrpcFromConfiguration not found. gRPC services were not registered."); Console.WriteLine("Make sure your project has source generators enabled and references Svrnty.CQRS.Grpc.Generators."); } return builder; } private static MethodInfo? FindExtensionMethod(string methodName) { // Search through all loaded assemblies for the extension method foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies()) { try { var types = assembly.GetTypes() .Where(t => t.IsClass && t.IsSealed && !t.IsGenericType && t.IsPublic); foreach (var type in types) { var method = type.GetMethod(methodName, BindingFlags.Static | BindingFlags.Public, null, new[] { typeof(IServiceCollection) }, null); if (method != null) return method; } } catch { // Skip assemblies that can't be inspected } } return null; } }