D
D
D8i2019-04-30 16:03:50
.NET
D8i, 2019-04-30 16:03:50

How to get interface implementations from ServiceProvider?

Hello. A few days does not allow to live normally one problem.
There is a .net core application, I use Microsoft.Extensions.DependencyInjection in it. I wanted to implement the so-called CommandHandler, which searches for the required class by line and executes the Execute method.
The class is like this:

[Command("time")]
    public class TimeCommand : ICommand
    {
        private readonly IVkApi _vkApi;

        public TimeCommand(IVkApi vkApi)
        {
            _vkApi = vkApi;
        }

        public void Execute(Message message)
        {
            _vkApi.Messages.Send(new MessagesSendParams
            {
                RandomId = DateTime.Now.Millisecond,
                PeerId = message.PeerId,
                Message = DateTime.Now.ToString(CultureInfo.InvariantCulture)
            });
        }
    }

How can I make sure that all implementations of the ICommand interface are automatically added to the ServiceProvider and how can I get them later in another class? Or is it done in some other way?
Now I have the following code:
ConfigureServices method:
private static ServiceProvider ConfigureServices()
        {
            var services = new ServiceCollection()
                .AddLogging(builder => builder.AddConsole()).AddTransient(typeof(VkLongPollService))
                .AddSingleton<IConfiguration>(provider =>
                {
                    var confBuilder = new ConfigurationBuilder()
                        .SetBasePath(Directory.GetCurrentDirectory())
                        .AddJsonFile("Configuration/Settings.json");
                    return confBuilder.Build();
                })
                .AddSingleton<IVkApi>(provider =>
                {
                    var vkApi = new VkApi();
                    vkApi.Authorize(new ApiAuthParams
                    {
                        AccessToken = provider.GetRequiredService<IConfiguration>()["VkAccessToken"]
                    });
                    return vkApi;
                })
                .AddSingleton<VkLongPollService>();

            services.AddSingleton<ICommand, TimeCommand>();

            services.AddSingleton<CommandHandlingService>();

            return services.BuildServiceProvider();
        }
    }

CommandHandlingService class:
public class CommandHandlingService
    {
        private readonly IServiceProvider _provider;

        public CommandHandlingService(IServiceProvider provider)
        {
            _provider = provider;
        }

        public void Process(Message message)
        {
            
            var commandStr = message.Text.Substring(1).Split(" ");
            ICommand command = null;
            foreach (var service in _provider.GetServices<ICommand>())
            {
                if (((Command) Attribute.GetCustomAttribute(service.GetType(), typeof(Command))).Display.Equals(commandStr[0]))
                {
                    command = service;
                    break;
                };
            }

            command?.Execute(message);
        }
    }

Those. in fact, now to create a command, I need to create a class and register it in the ServiceProvider, but I want to make it enough to create an interface implementation class to create a command. I found information that I can add what I need to the serviceprovider in a cycle, but only with Type, and with types I can’t do anything.

Answer the question

In order to leave comments, you need to log in

1 answer(s)
N
Nikolay, 2019-04-30
@D8i

https://medium.com/agilix/asp-net-core-inject-all-...

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question