در توسعه نرم‌افزار، یکی از الگوهای طراحی مهم که به کاهش پیچیدگی و بهبود قابلیت تست‌پذیری کمک می‌کند، Dependency Injection (DI) است. این الگو در اکثر فریم‌ورک‌های مدرن مانند .NET Core، جاوا و پایتون به‌طور گسترده استفاده می‌شود. در این مقاله، به بررسی استفاده از DI در برنامه‌های ویندوز فرم با .NET Core پرداخته و یک مشکل رایج که ممکن است هنگام استفاده از DI در ویندوز فرم‌ها پیش آید، یعنی سازنده‌های مبهم (Ambiguous Constructor) را بررسی خواهیم کرد.
کینگتو - آموزش برنامه نویسی تخصصصی - دات نت - سی شارپ - بانک اطلاعاتی و امنیت

Dependency Injection در ویندوز فرم و مشکل سازنده‌های مبهم آن

22 بازدید 0 نظر ۱۴۰۴/۰۲/۲۰

Dependency Injection در .NET Core

Dependency Injection (DI) یک الگوی طراحی است که به کمک آن می‌توان وابستگی‌ها (dependencies) بین اجزای مختلف یک برنامه را از طریق DI container به‌طور خودکار تزریق کرد. در .NET Core، DI به‌طور پیش‌فرض در فریم‌ورک گنجانده شده است و می‌توان به راحتی از آن برای مدیریت وابستگی‌ها استفاده کرد.

وابستگی‌ها در ویندوز فرم

در برنامه‌های ویندوز فرم، گاهی نیاز به استفاده از DI برای مدیریت وابستگی‌ها در طول عمر فرم‌ها و دیگر کلاس‌ها داریم. استفاده از DI در این برنامه‌ها به‌ویژه در پروژه‌هایی با مقیاس بزرگ می‌تواند کمک زیادی به ساختار کد و نگهداری آن کند.

مشکل سازنده‌های مبهم

هنگامی که می‌خواهیم وابستگی‌ها را از طریق DI به سازنده‌های یک کلاس منتقل کنیم، ممکن است در صورت وجود چند سازنده با پارامترهای مختلف در کلاس، مشکلی به نام سازنده‌های مبهم (Ambiguous Constructors) به وجود آید. این مشکل زمانی رخ می‌دهد که DI container قادر به شناسایی سازنده مناسب برای کلاس نباشد.

علت وقوع این مشکل

این مشکل زمانی پیش می‌آید که کلاس مورد نظر بیش از یک سازنده (constructor) داشته باشد و DI container نتواند تصمیم بگیرد که کدام یک از این سازنده‌ها را انتخاب کند. برای مثال، اگر کلاس frmMain دو سازنده با پارامترهای مختلف داشته باشد، DI container نمی‌تواند به‌طور خودکار تشخیص دهد که کدام سازنده را برای تزریق وابستگی‌ها انتخاب کند.

 

مثال: کد مبهم

فرض کنید کلاسی به نام frmMain دارید که به‌صورت زیر تعریف شده است:

public partial class frmMain : Form
{
    private readonly IFriendService _friendService;
    private readonly IFormFactory _formFactory;

    // سازنده اول با پارامترهای وابستگی
    public frmMain(IFriendService friendService, IFormFactory formFactory)
    {
        InitializeComponent();
        _friendService = friendService;
        _formFactory = formFactory;
    }

    // سازنده دوم با IServiceProvider
    public frmMain(IServiceProvider serviceProvider)
    {
        var friendService = serviceProvider.GetRequiredService<IFriendService>();
        var formFactory = serviceProvider.GetRequiredService<IFormFactory>();
        _friendService = friendService;
        _formFactory = formFactory;
    }
}

 

در اینجا، DI container نمی‌تواند انتخاب کند که از کدام سازنده استفاده کند. این مشکل باعث می‌شود که هنگام راه‌اندازی فرم frmMain با خطای سازنده مبهم مواجه شوید.

حل مشکل سازنده‌های مبهم

برای رفع این مشکل، باید اطمینان حاصل کنیم که فقط یک سازنده در کلاس موجود باشد که از آن بتوان برای تزریق وابستگی‌ها استفاده کرد. در حالت کلی، توصیه می‌شود که از سازنده‌ای که به‌طور مستقیم وابستگی‌ها را دریافت می‌کند استفاده کنید و سازنده‌هایی که از IServiceProvider استفاده می‌کنند را حذف کنید.

راه‌حل

در این مثال، ما سازنده‌ای که از IServiceProvider استفاده می‌کند را حذف می‌کنیم و از سازنده‌ای که وابستگی‌ها را به‌طور مستقیم دریافت می‌کند، استفاده می‌کنیم:

public partial class frmMain : Form
{
    private readonly IFriendService _friendService;
    private readonly IFormFactory _formFactory;

    // سازنده با پارامترهای وابستگی
    public frmMain(IFriendService friendService, IFormFactory formFactory)
    {
        InitializeComponent();
        _friendService = friendService;
        _formFactory = formFactory;

        // سایر تنظیمات فرم
        flowMessages.FlowDirection = FlowDirection.TopDown;
        flowMessages.WrapContents = false;
        flowMessages.AutoScroll = true;
        flowMessages.Dock = DockStyle.Fill;
    }
}

با این کار، تنها یک سازنده در کلاس frmMain وجود خواهد داشت و دیگر مشکلی از نظر انتخاب سازنده برای DI container نخواهیم داشت.

ثبت وابستگی‌ها در DI container

حالا که سازنده‌مان تنها یک سازنده مناسب دارد، باید اطمینان حاصل کنیم که تمامی وابستگی‌ها در ConfigureServices به درستی ثبت شده‌اند.

public static void Main()
{
    Application.EnableVisualStyles();
    Application.SetCompatibleTextRenderingDefault(false);

    var host = Host.CreateDefaultBuilder()
        .ConfigureServices((context, services) =>
        {
            // ثبت DbContext
            services.AddDbContext<DataBaseContext>(options =>
                options.UseSqlServer("YourConnectionStringHere"));

            // ثبت سرویس‌ها
            services.AddScoped<IDataBaseContext, DataBaseContext>();
            services.AddScoped<IFormFactory, FormFactory>();
            services.AddScoped<IFriendService, FriendService>();
            services.AddScoped<InputDialogForm>();
            services.AddScoped<frmMain>(); // ثبت frmMain
        })
        .Build();

    var scope = host.Services.CreateScope();
    var mainForm = scope.ServiceProvider.GetRequiredService<frmMain>();
    Application.Run(mainForm);
}

با این کد، وابستگی‌ها به‌درستی ثبت شده‌اند و برنامه می‌تواند به‌طور صحیح frmMain را با استفاده از DI راه‌اندازی کند.

نتیجه‌گیری

در این مقاله، ما به بررسی چگونگی استفاده از Dependency Injection در برنامه‌های ویندوز فرم با استفاده از .NET Core پرداختیم و به بررسی مشکلی به نام سازنده‌های مبهم که ممکن است در هنگام استفاده از DI در ویندوز فرم‌ها پیش آید، پرداختیم. با حذف سازنده‌های اضافی و اطمینان از ثبت درست وابستگی‌ها در DI container، این مشکل قابل رفع است و می‌توان به‌راحتی از DI در ویندوز فرم‌ها استفاده کرد.

استفاده از DI در برنامه‌های ویندوز فرم به توسعه‌دهندگان کمک می‌کند تا کدهای خود را مرتب‌تر و مقیاس‌پذیرتر کنند و در عین حال قابلیت تست‌پذیری را افزایش دهند.

 

لینک استاندارد شده: V4b2KsR

0 نظر

    هنوز نظری برای این مقاله ثبت نشده است.