Как вы используете внедрение зависимостей в консольном приложении asp.net?

Я делаю что-то вроде:

        private static  IServiceProvider serviceProvider;

    public Program(IApplicationEnvironment env, IRuntimeEnvironment runtime)
    {
        var services = new ServiceCollection();
        ConfigureServices(services);
        serviceProvider = services.BuildServiceProvider();

        // Set up configuration sources.
        var builder = new ConfigurationBuilder()
            .AddJsonFile("appsettings.json")
            .AddEnvironmentVariables();

        Configuration = builder.Build();
    }
    public IConfigurationRoot Configuration { get; set; }

    private void ConfigureServices(IServiceCollection services)
    {
        //Console.WriteLine(Configuration["Data:DefaultConnection:ConnectionString"]);

        services.AddEntityFramework()
            .AddSqlServer()
            .AddDbContext<DbContext>(options =>
                options.UseSqlServer(Configuration["Data:DefaultConnection:ConnectionString"]));
    }

Я изо всех сил пытаюсь использовать программу, используя введенный DbContext. Любая идея? Как вы создаете экземпляр программы и получаете все необходимое? Я не знаю, что делать в статическом методе Main.

Есть ли для этого эквивалент?

public static void Main(string[] args) => WebApplication.Run<Startup>(args);

Что-то вроде?

public static void Main(string[] args) => ConsoleApplication.Run<Program>(args);

2 ответа

Решение

Вот как я это сделал:

public class Startup
{
    public static IConfigurationRoot Configuration { get; set; }

    public static void ConfigureServices(IServiceCollection services)
    {
        services.AddEntityFramework()
            .AddSqlServer()
            .AddDbContext<DbContext>(options =>
                options.UseSqlServer(Configuration["Data:DefaultConnection:ConnectionString"]));

        services.AddSingleton<IMyManager, Manager>();
        services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
        services.AddSingleton<Program, Program>();
    }

    public static void Main(string[] args)
    {
        var services = new ServiceCollection();
        var builder = new ConfigurationBuilder()
            .AddJsonFile("appsettings.json");
            .AddEnvironmentVariables()
            .AddUserSecrets();
        Configuration = builder.Build();
        ConfigureServices(services);
        var provider = services.BuildServiceProvider();

        CancellationTokenSource ctSource = new CancellationTokenSource();
        CancellationToken ct = ctSource.Token;

        Task task = Task.Run(async () =>
        {
            Program program = provider.GetRequiredService<Program>();
            await program.Run(ct);
        });
        try
        {
            task.Wait();
        }
        catch (AggregateException e)
        {
            throw e.InnerException;
        }
        ctSource.Cancel();
        ctSource.Dispose();
    }
}

Тогда программа просто:

class Program
{
    private IMyManager _myManager;

    public Program(IMyManager myManager)
    {
        _myManager = myManager;
    }

    public async Task Run(CancellationToken cancelationToken)
    {
        while (true)
        {
            cancelationToken.ThrowIfCancellationRequested();

            // My things using _myManager

            await Task.Delay(10000, cancelationToken);
        }
    }
}

Я удалил кучу материала для примера, так что он, вероятно, где-то вылетает, но вы поняли идею.

На всякий случай, если кто-то еще ищет маленький и простой пример для подражания.

Вот небольшое консольное приложение, которое я недавно написал для примера. Это всего лишь небольшая демонстрация DI генератора паролей в приложении с юнит-тестами.

https://github.com/AnthonySB/PasswordApplication

using System;
using Microsoft.Extensions.DependencyInjection;
using PasswordExercise.Interfaces;
using PasswordExercise.Services;

namespace PasswordExercise
{
    class Program
    {
        static void Main(string[] args)
        {
            //Dependency injection
            var serviceProvider = new ServiceCollection()
                .AddSingleton<IPasswordGeneratorService, PasswordGenerator>()
                .AddSingleton<IPasswordService, PasswordService>()
                .BuildServiceProvider();

            //Get the required service
            var passwordService = serviceProvider.GetService<IPasswordService>();

            //For reading from the console
            ConsoleKeyInfo key;

            //Display the menu
            passwordService.Menu();

            do
            {
                //Read the console key, do not display on the screen
                key = Console.ReadKey(true);

                switch (key.KeyChar.ToString())
                {
                    case "1":

                        Console.WriteLine("Simple password: {0}", passwordService.SimplePassword());
                        break;
                    case "2":
                        Console.WriteLine("Moderate password: {0}", passwordService.ModeratePassword());
                        break;
                    case "3":
                        Console.WriteLine("Strong password: {0}", passwordService.StrongPassword());
                        break;
                }
            } while (key.Key != ConsoleKey.Escape);
        }
    }
}

Надеюсь, это кому-нибудь поможет.

Другие вопросы по тегам