برنامه نویسی

یادداشت های یادگیری .NET: تزریق وابستگی

منابع:
مایکروسافت: وابستگی به
یوتیوب: YZK

“کنترل معکوس” در زندگی: تولید برق (آن را کنترل کنید) و شبکه برق (کنترل شبکه برق ، استفاده از کاربر).
تزریق وابستگی (DI) اجرای وارونگی کنترل (IOC) است.
با تکیه بر فرآیند مونتاژ ساده سازی ماژول و کاهش اتصال بین ماژول ها.

هدف از معکوس کنترل کد:
“نحوه ایجاد اشیاء xx” -> “من اشیاء xx را می خواهم”
دو روش اجرای: موقعیت یابی سرویس ، تزریق وابستگی (DI ، روش اصلی)

مفهوم DI:

  • وابستگی: وابستگی شیئی است که یک شیء دیگر به آن بستگی دارد.
  • سرویس: هدف به چارچوب ؛
  • سرویس ثبت نام:
  • کانتینر خدمات: مسئول خدمات ثبت نام مدیریت ؛
  • سرویس پرس و جو: ایجاد اشیاء و اشیاء مرتبط ؛
  • چرخه عمر شیء (زودگذر) ؛

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

  • dotnet افزودن بسته microsoft.extensions.dookendencyinjection -version 9.0.1
  • با استفاده از Microsoft.Extensions.DependencyInjection
  • یک نمونه جدید ServiceCollection ایجاد کنید ، سپس خدمات را در ServiceCollection ثبت و پیکربندی کنید.
  • ServiceCollection برای ساخت شیء کانتینر IServiceProvider. فراخوانی ServiceCollection's BuildServiceProvider برای ایجاد یک سرویس دهنده ، که می تواند برای به دست آوردن اشیاء موجود در سرویس دهنده قبل از ایجاد سرویس دهنده استفاده شود.

چرخه زندگی خدمات:

  • گذرا (هر بار که از ظرف سرویس درخواست می شود ایجاد شده است.) ؛ scoped (برای برنامه های وب ، یک طول عمر scoped نشان می دهد که خدمات یک بار در هر درخواست/اتصال مشتری ایجاد می شوند). Singleton (هر درخواست بعدی اجرای خدمات از ظرف تزریق وابستگی از همان نمونه استفاده می کند ، خدمات Singleton باید از موضوع ایمن باشد و اغلب در خدمات بدون تابعیت استفاده می شود.)
  • برای دیدن اشیاء مختلف چرخه زندگی ، به سازنده کلاس چاپ کنید ، از ServiceProvider.CreateScope () برای ایجاد دامنه (Scope.ServiceProvider به جای سرویس جهانی) استفاده کنید. در محدوده نابود شده و مرجع خارجی خالی است.
  • اگر یک کلاس رابط IDISPABLE را پیاده سازی کند ، ظرف پس از خروج از قسمت ، به طور خودکار روش دفع شی را فراخوانی می کند.
  • در هسته ASP.NET ، شیء چرخه زندگی کوتاه را نقل نکنید.
  • انتخاب چرخه زندگی: در صورت عدم وجود وضعیتی ، توصیه می شود که یک حالت وجود داشته باشد ، اگر یک حالت وجود داشته باشد ، یک کنترل دامنه وجود دارد و توصیه می شود که دامنه باشد ، زیرا کد تحت این کنترل دامنه در این زمینه اجرا می شود موضوع مشابه.
  • بسیاری از روش های بار سنگین برای سرویس کتاب گروه .NET وجود دارد.

از هر یک از روش های ثبت نام خدمات می توان برای ثبت چندین نمونه خدمات از همان نوع خدمات استفاده کرد. تماس زیر هنگام حل و فصل سرویس ، مورد قبلی را تحت الشعاع قرار می دهد و هنگامی که چندین سرویس از طریق IEnumerable حل می شود ، به برنامه قبلی اضافه می کند ، خدمات به ترتیب آنها هنگام ثبت نام از طریق IEnumerable ظاهر می شوند.

IServiceProvider Service Positioner روش:

  • t getService () اگر جسم به دست نیامد ، تهی را برگردانید
  • Object GetService (نوع ServiceType)
  • t getRequiredService () اگر نتوانید شیء را بدست آورید ، غیر طبیعی خواهید بود
  • Object GetRequiredService (نوع ServiceType)
  • سرویس های بی نظیر () مناسب است
  • Ienumerable GetServices (نوع ServiceType)

تزریق وابستگی “مسری” است. به صورت دستی این شیء هیچ ارتباطی با DI ندارد.
پیش فرض DI از .NET تزریق سازنده است

به عنوان مثال یک کلاس بنویسید ، پایگاه داده را برای عملکرد درج وصل کنید و ورود به سیستم (خروجی آنالوگ) را ضبط کنید و DAO و سیاهههای مربوط را در یک کلاس سرویس جداگانه قرار دهید.

using Microsoft.Extensions.DependencyInjection;

ServiceCollection services = new ServiceCollection();

services.AddScoped();
services.AddScoped();
services.AddScoped();
services.AddScoped();

using (var sp = services.BuildServiceProvider())

{
// 所有的成员变量,都会被框架创建并赋值
var c = sp.GetRequiredService();

c.Test();
}


class Controller

{
private readonly ILog log;

private readonly IStorage storage;

public Controller (ILog log, IStorage storage)

{
this.log = log;

this.storage = storage;

}


public void Test()

{
this.log.Log("start upload...");
this.storage.Save("sdflkjljioweuriowueroiweu", "1.txt");

this.log.Log("finish upload....");
}
}


interface ILog

{
public void Log(String msg);

}


class LogImpl : ILog

{
public void Log(string msg)

{
Console.WriteLine($"log: {msg}");

}
}


interface IConfig

{
public string GetValue(string name);

}


class ConfigImpl : IConfig

{
public string GetValue(string name)

{
return "hello";

}
}


interface IStorage

{
public void Save(string content, string name);

}


class StorageImpl : IStorage

{
private readonly IConfig config;

public StorageImpl(IConfig config)

{
this.config = config;

}
public void Save(string content, string name)

{
string server = config.GetValue("serve");

Console.WriteLine($"upload to {server}, file name is {name}, content is {content}");

}
}
حالت تمام صفحه را وارد کنید

از حالت تمام صفحه خارج شوید

چندین قوانین کشف سازنده

  • هنگامی که یک نوع بیش از یک سازنده را تعریف می کند ، ارائه دهنده خدمات منطقی برای تعیین سازنده برای استفاده دارد. سازنده با بیشترین پارامترهایی که انواع آنها قابل حل هستند انتخاب می شوند.
  • اگر در هنگام کشف سازندگان ابهام وجود داشته باشد ، یک استثناء پرتاب می شود. شما می توانید با تعریف سازنده ای که به جای آن هر دو نوع قابل حل DI را می پذیرند ، از ابهام جلوگیری کنید.

خلاصه:
به جای تمرکز روی اجرای ، به رابط توجه کنید و هر سرویس می تواند ساکرای بیشتری داشته باشد. هنگام نوشتن کد ، نیازی به دانستن اجرای خدمات خاص نیست.

نوشته های مشابه

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *

دکمه بازگشت به بالا