มีวิธีที่แข็งแกร่งในการลงทะเบียนการพึ่งพาใน 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

นอกจากสิ่งที่ได้กล่าวไปแล้ว

ส่วนตัวผมชอบที่จะมีชั้นเรียนแยกต่างหากที่ลงทะเบียนการอ้างอิงต่อการชุมนุมแต่ละ สิ่งนี้จะเพิ่มการควบคุมเพิ่มเติมเกี่ยวกับการใช้คลาสที่เลเยอร์ด้านขวาและช่วยให้สามารถใช้internalIMO ได้ดี

ไม่ว่าจะใช้scanกลไกหรือไม่ก็ขึ้นอยู่กับคุณ เฟรมเวิร์กบางตัวให้สิ่งนี้ตามค่าเริ่มต้น การจัดกลุ่มการพึ่งพาที่คล้ายกันในชุดของคลาส / วิธีการในทางกลับกันควรช่วยในการแก้ไขตรรกะในสถานที่ที่สอดคล้องกันสำหรับการเปลี่ยนแปลงใด ๆ คุณสามารถรวมวิธีการทั้งสองเข้าด้วยกัน

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.