. net Ядро регистрирует все сервисы из данной сборки - PullRequest
0 голосов
/ 16 апреля 2020

Что я должен сделать, чтобы динамически отобразить все сервисы в моей регистрации сервис-хоста 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 .

1 Ответ

0 голосов
/ 20 апреля 2020

Мое отражение-фу сейчас несколько слабое, но я бы сказал, что вы уже на 80%. Что вы можете сделать, когда найдете интересующие вас типы, так это вызвать метод интереса через рефлексию.

services.AddGrpcServer<ISimpleActionService, SimpleActionService>(new GrpcServerOptions { Url = "127.0.0.1", Port = 5000 });

становится чем-то вроде

var methodInfo = services.GetType().GetMethod("AddGrpcServer").MakeGenericMethod(new []{ yourInterfaceType, yourImplType }).Invoke(new GrpcServerOptions { Url = "127.0.0.1", Port = 5000 });

Нельзя заменять типы в обобщениях во время выполнения, не обращаясь к MakeGenericType / MakeGenericMethod et c из отражения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...