динамически регистрировать сервисы в startup.cs - PullRequest
0 голосов
/ 10 января 2020

Я пытаюсь динамически зарегистрировать сервисы в startup.cs. У меня проблемы с вызовом метода из динамически типизированного объекта.

Шаги

  1. Создать интерфейс с методом;
    public interface ICustBillTypeService
    { public static void RegisterTypeServices(IServiceCollection services) { } }
Создать класс из интерфейса. Метод принимает ServiceCollection и добавляет соответствующий ServiceDescriptor.
    public class RPT628Registration : ICustBillTypeService
    {
        public static void RegisterTypeServices(IServiceCollection services)
        { services.AddScoped<RPT628Service>();}
    }
Идентифицирует все классы в сборке, которые реализуют ICustBillTypeService и возвращают имя класса.
            var results = Assembly.GetExecutingAssembly()
                    .GetTypes()
                    .Where(x => typeof(ICustBillEntityService).IsAssignableFrom(x) 
                        && !x.IsInterface 
                        && !x.IsAbstract)
                    .Select(x => x.Name).ToList();
Для каждого найденного класса вызовите метод интерфейса, реализованный этим классом, чтобы добавить службу в коллекцию ServiceCollection. Здесь я сталкиваюсь с проблемами. Шаг 3 возвращает имя всех типов, которые реализуют интерфейс. Я могу просмотреть каждый результат, определить тип и создать экземпляр типа, но не могу добраться до метода класса, потому что мой объект динамически типизируется во время выполнения и имеет доступ только к определению базового объекта
            foreach(var result in results)
            {
                Type resultType = Type.GetType(result);
                var t = Activator.CreateInstance(resultType);
    -->         t.RegisterTypeServices(services);  //fails the build because the method is not part of the object until run time.
            }

Я бы предпочел не называть "строковое" имя метода. В любом случае можно ли использовать интерфейс с «т», чтобы я мог вызвать имя метода?

1 Ответ

0 голосов
/ 10 января 2020

Пока писал, я понял это. Это требует, чтобы имя метода передавалось в виде строки, но я могу жить с этим.

///  Add "GetTypeServices(services)" to ConfigureServices in Startup.cs;


        public void GetTypeServices(IServiceCollection services)
        {
            var results = Assembly.GetExecutingAssembly().GetTypes()
                    .Where(x => typeof(ICustBillTypeService).IsAssignableFrom(x) 
                        && !x.IsInterface 
                        && !x.IsAbstract)
                    .Select(x => x.FullName).ToList();

            foreach(var result in results)
            {
                Type resultType = Type.GetType(result);
                MethodInfo typeMethod = resultType.GetMethod("RegisterTypeServices");                
                var t = Activator.CreateInstance(resultType);
                dynamic methodResult = typeMethod.Invoke(t, new object[] { services });                
            }
        }

Теперь Startup.cs не нужно изменять, когда нам нужно добавить новый сервис. Пока разработчик создает новый класс, наследующий интерфейс, он будет обнаружен автоматически.

...