Что я должен сделать, чтобы динамически отобразить все сервисы в моей регистрации сервис-хоста grp c, вместо того, чтобы просто отображать их по одному и редактировать этот фрагмент кода каждый раз, когда я добавляю новый сервис?
I Мне удалось получить все типы в сборке, которые находятся в GrpcServices и имеют мой пользовательский атрибут, используя этот код:
public IEnumerable<Type> FindServiceInterfaces()
{
string definedIn = typeof(GrpcServiceAttribute).Assembly.GetName().Name;
Assembly assembly = AppDomain.CurrentDomain.GetAssemblies().FirstOrDefault(x => x.GetName().Name.Equals("GrpcServices"));
foreach (Type type in assembly.GetTypes())
if (type.GetCustomAttributes(typeof(GrpcServiceAttribute), true).Length > 0)
yield return type;
}
Но я не знаю, как привести / создать эти вышеупомянутые типы и использовать их следующим образом но в общем / Dynami c способ:
var serverHostBuilder = new HostBuilder()
.ConfigureServices((hostContext, services) =>
{
services.AddGrpcServer<ISimpleActionService, SimpleActionService>(new GrpcServerOptions { Url = "127.0.0.1", Port = 5000 });
});
public static class ServiceCollectionExtensions
{
public static IServiceCollection AddGrpcServer<TServiceInterface, TServiceImplementation>(
this IServiceCollection serviceCollection,
GrpcServerOptions options,
ISerializer serializer
)
where TServiceInterface : class, IGrpcService
where TServiceImplementation : class, IGrpcService, TServiceInterface
{
serviceCollection.AddScoped<TServiceInterface, TServiceImplementation>();
serviceCollection.AddSingleton<GrpcHost<TServiceInterface>>(
appServices => GrpcHostFactory.Create<TServiceInterface>(appServices, options, serializer)
);
serviceCollection.AddSingleton<IHostedService, GrpcBackgroundService<TServiceInterface>>();
return serviceCollection;
}
}
Желаемое решение: просто перебрать все интерфейсы, которые имеют мой атрибут, найти класс, который реализует этот интерфейс IFoo -> Foo и добавить это -> services.AddGrpcServer<IFoo,Foo>(.....)
Единственное решение, которое я нашел для создания экземпляра этого объекта, - это приведение к уже известному типу, подобному следующему:
var desiredClass = (DesiredClassType)Activator.CreateInstance(assemblyType)
, что для меня явно не является решением.
РЕДАКТИРОВАТЬ:
Я обнаружил нюгет, подобный Scrutor, и для меня это почти решение, закодированное таким образом (кстати, это решение для клиента, которому требуется только интерфейс вместо интерфейса и его класс реализации)
var clientServices = new ServiceCollection()
.Scan(scan => scan
.FromAssembliesOf(grpcServiceInterfaces)
.AddClasses(cl => cl.AssignableToAny(grpcServiceInterfaces))
.AsImplementedInterfaces()
.WithSingletonLifetime())
//.AddGrpcClient<ISimpleActionService> (clientOptions)
.BuildServiceProvider();
, но я все еще не знаю, как выполнить мой пользовательский AddSingletonMethod, который выполняет метод Create из GrpcHostFactory .