Чи існує надійний спосіб зареєструвати залежності в ASP.NET Core 3.1, окрім додавання всього до класу запуску?


9

У мене є проект ASP.NET Core 3.1. Як правило, я реєструю будь-яку залежність, використовуючи ConfigureServices()метод у Startup.csкласі.

Але я вважаю, що мені потрібно зареєструвати багато залежностей, і ConfigureServices()виглядає це величезно! Я знаю, що, ймовірно, я можу створити метод розширення статичного методу і викликати його з класу ConfigureService () `, але цікаво, чи є кращий спосіб.

Якщо є спосіб реєструвати залежності в контейнері IoC, не визначаючи їх одна за одною

services.AddScoped<Interface, Class>();
.... 200 lines later
services.AddScoped<ISettings, Settings>()

Відповіді:


10

Групування залежних залежностей у спеціальні методи розширення - це дуже поширений спосіб зробити це. ASP.NET Core вже робить це для багатьох внутрішніх служб, і ви можете легко розширити поверх цього і налаштувати їх так, як потрібно для вашої програми. Наприклад, щоб встановити автентифікацію та авторизацію:

public IServiceCollection AddSecurity(this IServiceCollection services)
{
    services.AddAuthentication()
        .AddCookie();

    service.AddAuthorization(options =>
    {
        options.DefaultPolicy = …;
    });

    return services;
}

Ви можете зробити те ж саме для служб, що стосуються додатків, і згрупувати їх логічно в окремі методи розширення.

Якщо у вас дуже багато подібних реєстрацій послуг, ви також можете використовувати реєстрацію на основі конвенції, наприклад, використовуючи Scrutor . Наприклад, це реєструє всі сервіси в певному просторі імен як перехідні для відповідного інтерфейсу:

services.Scan(scan => scan
    .FromAssemblyOf<Startup>()
        .AddClasses(c => c.InNamespaces("MyApp.Services"))
            .AsImplementedInterfaces()
            .WithTransientLifetime()
);

Scrutor дозволяє виконувати дуже складні правила сканування послуг, тому, якщо ваші служби дотримуються певної схеми, ви, ймовірно, зможете придумати для цього правило.


3

Створіть спеціальний атрибут (званий AutoBindAttribute)

public class AutoBindAttribute : Attribute
{
}

Використовуйте його як нижче (прикрасьте всі реалізації, які ви хочете автоматично зв’язувати з [AutroBind])

public interface IMyClass {}

[AutoBind]
public class MyClass : IMyClass {}

Тепер створіть метод розширення для IServiceCollection

public class ServiceCollectionExtentions
{
    public static void AutoBind(this IServiceCollection source, params Assembly[] assemblies)
    {
       source.Scan(scan => scan.FromAssemblies(assemblies)
        .AddClasses(classes => classes.WithAttribute<AutoBindAttribute>())
        .AsImplementedInterfaces()
        .WithTransientLifetime();
    }
}

Тепер зателефонуйте в Startup.cs

public class Startup
{

    public void ConfigureServices(IServiceCollection services)
    {
        services.AutoBind(typeof(Startup).Assembly);
    }

}

Примітка: Ви можете вдосконалити ServiceCollectionExtentionsклас для підтримки всіх областей, таких як одиночний тощо. Цей приклад показаний лише для перехідного життя.

Насолоджуйтесь !!!


0

Окрім сказаного.

Особисто мені подобається мати окремий клас, який реєструє залежності на кожну збірку. Це додає більше контролю над використанням класів на потрібному шарі і дозволяє зробити їх, internalякі ІМО хороші.

Незалежно від того, використовувати scanмеханізми чи ні. Деякі рамки дають це за замовчуванням. Групування подібних залежностей у наборі класів / методів, у свою чергу, повинно сприяти збереженню розв’язувальної логіки в послідовному місці для будь-яких змін. Можна поєднувати обидва підходи.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.