dotnet-cqrs/Svrnty.CQRS.Grpc/CqrsBuilderExtensions.cs

73 lines
2.4 KiB
C#

#nullable enable
using System;
using System.Linq;
using System.Reflection;
using Microsoft.Extensions.DependencyInjection;
using Svrnty.CQRS.Configuration;
namespace Svrnty.CQRS.Grpc;
/// <summary>
/// Extension methods for CqrsBuilder to add gRPC support
/// </summary>
public static class CqrsBuilderExtensions
{
/// <summary>
/// Adds gRPC support to the CQRS pipeline
/// </summary>
/// <param name="builder">The CQRS builder</param>
/// <param name="configure">Optional configuration for gRPC endpoints</param>
/// <returns>The CQRS builder for method chaining</returns>
public static CqrsBuilder AddGrpc(this CqrsBuilder builder, Action<GrpcCqrsOptions>? 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;
}
}