Bagikan melalui


Injeksi dependensi ke pengontrol dalam ASP.NET Core

Oleh Rick Anderson

ASP.NET Core pengontrol MVC meminta dependensi secara eksplisit melalui konstruktor. ASP.NET Core memiliki dukungan bawaan untuk injeksi ketergantungan (DI). DI membuat aplikasi lebih mudah diuji dan dikelola.

Melihat atau mengunduh kode sampel (cara mengunduh)

Injeksi konstruktor

Layanan ditambahkan sebagai parameter konstruktor, dan runtime menyelesaikan layanan dari kontainer layanan. Layanan biasanya didefinisikan menggunakan antarmuka. Misalnya, pertimbangkan aplikasi yang memerlukan waktu saat ini. Antarmuka berikut mengekspos layanan:

public interface IDateTime
{
    DateTime Now { get; }
}

Kode berikut mengimplementasikan antarmuka:

public class SystemDateTime : IDateTime
{
    public DateTime Now
    {
        get { return DateTime.Now; }
    }
}

Tambahkan layanan ke kontainer layanan:

public void ConfigureServices(IServiceCollection services)
{
    services.AddSingleton<IDateTime, SystemDateTime>();

    services.AddControllersWithViews();
}

Untuk informasi selengkapnya tentang , lihat Masa pakai layanan DI.

Kode berikut menampilkan salam kepada pengguna berdasarkan waktu hari:

public class HomeController : Controller
{
    private readonly IDateTime _dateTime;

    public HomeController(IDateTime dateTime)
    {
        _dateTime = dateTime;
    }

    public IActionResult Index()
    {
        var serverTime = _dateTime.Now;
        if (serverTime.Hour < 12)
        {
            ViewData["Message"] = "It's morning here - Good Morning!";
        }
        else if (serverTime.Hour < 17)
        {
            ViewData["Message"] = "It's afternoon here - Good Afternoon!";
        }
        else
        {
            ViewData["Message"] = "It's evening here - Good Evening!";
        }
        return View();
    }

Jalankan aplikasi dan pesan ditampilkan berdasarkan waktu.

Injeksi tindakan dengan

memungkinkan menyuntikkan layanan langsung ke metode tindakan tanpa menggunakan injeksi konstruktor:

public IActionResult About([FromServices] IDateTime dateTime)
{
    return Content( $"Current server time: {dateTime.Now}");
}

Injeksi tindakan dengan

Kode berikut menunjukkan cara mengakses layanan kunci dari kontainer DI dengan menggunakan atribut :

using Microsoft.AspNetCore.Mvc;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddKeyedSingleton<ICache, BigCache>("big");
builder.Services.AddKeyedSingleton<ICache, SmallCache>("small");
builder.Services.AddControllers();

var app = builder.Build();

app.MapControllers();

app.Run();

public interface ICache
{
    object Get(string key);
}
public class BigCache : ICache
{
    public object Get(string key) => $"Resolving {key} from big cache.";
}

public class SmallCache : ICache
{
    public object Get(string key) => $"Resolving {key} from small cache.";
}

[ApiController]
[Route("/cache")]
public class CustomServicesApiController : Controller
{
    [HttpGet("big")]
    public ActionResult<object> GetBigCache([FromKeyedServices("big")] ICache cache)
    {
        return cache.Get("data-mvc");
    }

    [HttpGet("small")]
    public ActionResult<object> GetSmallCache([FromKeyedServices("small")] ICache cache)
    {
        return cache.Get("data-mvc");
    }
}

Pengaturan akses dari pengontrol

Mengakses pengaturan aplikasi atau konfigurasi dari dalam pengontrol adalah pola umum. Pola options yang dijelaskan dalam pola Options dalam ASP.NET Core adalah pendekatan yang disukai untuk mengelola pengaturan. Umumnya, jangan langsung menyuntikkan ke pengontrol.

Buat kelas yang mewakili opsi. Contohnya:

public class SampleWebSettings
{
    public string Title { get; set; }
    public int Updates { get; set; }
}

Tambahkan kelas konfigurasi ke koleksi layanan:

public void ConfigureServices(IServiceCollection services)
{
    services.AddSingleton<IDateTime, SystemDateTime>();
    services.Configure<SampleWebSettings>(Configuration);

    services.AddControllersWithViews();
}

Konfigurasikan aplikasi untuk membaca pengaturan dari file berformat JSON:

public class Program
{
    public static void Main(string[] args)
    {
        CreateHostBuilder(args).Build().Run();
    }

    public static IHostBuilder CreateHostBuilder(string[] args) =>
        Host.CreateDefaultBuilder(args)
            .ConfigureAppConfiguration((hostingContext, config) =>
            {
                config.AddJsonFile("samplewebsettings.json",
                    optional: false,
                    reloadOnChange: true);
            })
            .ConfigureWebHostDefaults(webBuilder =>
            {
                webBuilder.UseStartup<Startup>();
            });
}

Kode berikut meminta pengaturan dari kontainer layanan dan menggunakannya dalam metode :

public class SettingsController : Controller
{
    private readonly SampleWebSettings _settings;

    public SettingsController(IOptions<SampleWebSettings> settingsOptions)
    {
        _settings = settingsOptions.Value;
    }

    public IActionResult Index()
    {
        ViewData["Title"] = _settings.Title;
        ViewData["Updates"] = _settings.Updates;
        return View();
    }
}

Pengontrol sebagai layanan

Secara default, ASP.NET Core tidak mendaftarkan pengontrol sebagai layanan dalam kontainer DI. Runtime menggunakan DefaultControllerActivator untuk membuat instans pengontrol dan menyelesaikan layanan dari kontainer DI untuk parameter konstruktor, tetapi pengontrol itu sendiri tidak diselesaikan dari kontainer.

Panggilan mendaftarkan semua pengontrol sebagai layanan dalam kontainer DI:

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddControllersWithViews().AddControllersAsServices();

Mendaftarkan pengontrol sebagai layanan memungkinkan:

  • Mencegat pembuatan pengontrol dengan kustom .
  • Menggunakan manajemen siklus hidup DI apa pun untuk kontroler.
  • Menyuntikkan layanan ke pengontrol menggunakan konstruktor terdaftar, karena kontainer DI memilih konstruktor.

Nota

Konfigurasikan sebelum memanggil . Lihat Berbagi pengontrol, tampilan, halaman Razor dan lainnya dengan Application Parts di ASP.NET Core untuk lebih jelasnya.

Sumber daya tambahan

  • Lihat logika pengontrol Test di ASP.NET Core untuk mempelajari cara membuat kode lebih mudah diuji dengan meminta dependensi secara eksplisit di pengontrol.
  • Dukungan kontainer injeksi dependensi layanan yang dikunci
  • Ganti kontainer injeksi dependensi default dengan implementasi pihak ketiga.

Oleh Rick Anderson dan Steve Smith

ASP.NET Core pengontrol MVC meminta dependensi secara eksplisit melalui konstruktor. ASP.NET Core memiliki dukungan bawaan untuk injeksi ketergantungan (DI). DI membuat aplikasi lebih mudah diuji dan dikelola.

Melihat atau mengunduh kode sampel (cara mengunduh)

Injeksi konstruktor

Layanan ditambahkan sebagai parameter konstruktor, dan runtime menyelesaikan layanan dari kontainer layanan. Layanan biasanya didefinisikan menggunakan antarmuka. Misalnya, pertimbangkan aplikasi yang memerlukan waktu saat ini. Antarmuka berikut mengekspos layanan:

public interface IDateTime
{
    DateTime Now { get; }
}

Kode berikut mengimplementasikan antarmuka:

public class SystemDateTime : IDateTime
{
    public DateTime Now
    {
        get { return DateTime.Now; }
    }
}

Tambahkan layanan ke kontainer layanan:

public void ConfigureServices(IServiceCollection services)
{
    services.AddSingleton<IDateTime, SystemDateTime>();

    services.AddControllersWithViews();
}

Untuk informasi selengkapnya tentang , lihat Masa pakai layanan DI.

Kode berikut menampilkan salam kepada pengguna berdasarkan waktu hari:

public class HomeController : Controller
{
    private readonly IDateTime _dateTime;

    public HomeController(IDateTime dateTime)
    {
        _dateTime = dateTime;
    }

    public IActionResult Index()
    {
        var serverTime = _dateTime.Now;
        if (serverTime.Hour < 12)
        {
            ViewData["Message"] = "It's morning here - Good Morning!";
        }
        else if (serverTime.Hour < 17)
        {
            ViewData["Message"] = "It's afternoon here - Good Afternoon!";
        }
        else
        {
            ViewData["Message"] = "It's evening here - Good Evening!";
        }
        return View();
    }

Jalankan aplikasi dan pesan ditampilkan berdasarkan waktu.

Injeksi tindakan dengan

memungkinkan menyuntikkan layanan langsung ke metode tindakan tanpa menggunakan injeksi konstruktor:

public IActionResult About([FromServices] IDateTime dateTime)
{
    return Content( $"Current server time: {dateTime.Now}");
}

Pengaturan akses dari pengontrol

Mengakses pengaturan aplikasi atau konfigurasi dari dalam pengontrol adalah pola umum. Pola options yang dijelaskan dalam pola Options dalam ASP.NET Core adalah pendekatan yang disukai untuk mengelola pengaturan. Umumnya, jangan langsung menyuntikkan ke pengontrol.

Buat kelas yang mewakili opsi. Contohnya:

public class SampleWebSettings
{
    public string Title { get; set; }
    public int Updates { get; set; }
}

Tambahkan kelas konfigurasi ke koleksi layanan:

public void ConfigureServices(IServiceCollection services)
{
    services.AddSingleton<IDateTime, SystemDateTime>();
    services.Configure<SampleWebSettings>(Configuration);

    services.AddControllersWithViews();
}

Konfigurasikan aplikasi untuk membaca pengaturan dari file berformat JSON:

public class Program
{
    public static void Main(string[] args)
    {
        CreateHostBuilder(args).Build().Run();
    }

    public static IHostBuilder CreateHostBuilder(string[] args) =>
        Host.CreateDefaultBuilder(args)
            .ConfigureAppConfiguration((hostingContext, config) =>
            {
                config.AddJsonFile("samplewebsettings.json",
                    optional: false,
                    reloadOnChange: true);
            })
            .ConfigureWebHostDefaults(webBuilder =>
            {
                webBuilder.UseStartup<Startup>();
            });
}

Kode berikut meminta pengaturan dari kontainer layanan dan menggunakannya dalam metode :

public class SettingsController : Controller
{
    private readonly SampleWebSettings _settings;

    public SettingsController(IOptions<SampleWebSettings> settingsOptions)
    {
        _settings = settingsOptions.Value;
    }

    public IActionResult Index()
    {
        ViewData["Title"] = _settings.Title;
        ViewData["Updates"] = _settings.Updates;
        return View();
    }
}

Pengontrol sebagai layanan

Secara default, ASP.NET Core tidak mendaftarkan pengontrol sebagai layanan dalam kontainer DI. Runtime menggunakan DefaultControllerActivator untuk membuat instans pengontrol dan menyelesaikan layanan dari kontainer DI untuk parameter konstruktor, tetapi pengontrol itu sendiri tidak diselesaikan dari kontainer.

Panggilan mendaftarkan semua pengontrol sebagai layanan dalam kontainer DI:

public void ConfigureServices(IServiceCollection services)
{
    services.AddControllersWithViews().AddControllersAsServices();
}

Mendaftarkan pengontrol sebagai layanan memungkinkan:

  • Mencegat pembuatan pengontrol dengan kustom .
  • Menggunakan manajemen siklus hidup DI apa pun untuk kontroler.
  • Menyuntikkan layanan ke pengontrol menggunakan konstruktor terdaftar, karena kontainer DI memilih konstruktor.

Nota

Konfigurasikan sebelum memanggil . Lihat Berbagi pengontrol, tampilan, halaman Razor dan lainnya dengan Application Parts di ASP.NET Core untuk lebih jelasnya.

Sumber daya tambahan

  • Lihat logika pengontrol Test di ASP.NET Core untuk mempelajari cara membuat kode lebih mudah diuji dengan meminta dependensi secara eksplisit di pengontrol.

  • Ganti kontainer injeksi dependensi default dengan implementasi pihak ketiga.

ASP.NET Core pengontrol MVC meminta dependensi secara eksplisit melalui konstruktor. ASP.NET Core memiliki dukungan bawaan untuk injeksi ketergantungan (DI). DI membuat aplikasi lebih mudah diuji dan dikelola.

Melihat atau mengunduh kode sampel (cara mengunduh)

Injeksi konstruktor

Layanan ditambahkan sebagai parameter konstruktor, dan runtime menyelesaikan layanan dari kontainer layanan. Layanan biasanya didefinisikan menggunakan antarmuka. Misalnya, pertimbangkan aplikasi yang memerlukan waktu saat ini. Antarmuka berikut mengekspos layanan:

public interface IDateTime
{
    DateTime Now { get; }
}

Kode berikut mengimplementasikan antarmuka:

public class SystemDateTime : IDateTime
{
    public DateTime Now
    {
        get { return DateTime.Now; }
    }
}

Tambahkan layanan ke kontainer layanan:

public void ConfigureServices(IServiceCollection services)
{
    services.AddSingleton<IDateTime, SystemDateTime>();

    services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
}

Untuk informasi selengkapnya tentang , lihat Masa pakai layanan DI.

Kode berikut menampilkan salam kepada pengguna berdasarkan waktu hari:

public class HomeController : Controller
{
    private readonly IDateTime _dateTime;

    public HomeController(IDateTime dateTime)
    {
        _dateTime = dateTime;
    }

    public IActionResult Index()
    {
        var serverTime = _dateTime.Now;
        if (serverTime.Hour < 12)
        {
            ViewData["Message"] = "It's morning here - Good Morning!";
        }
        else if (serverTime.Hour < 17)
        {
            ViewData["Message"] = "It's afternoon here - Good Afternoon!";
        }
        else
        {
            ViewData["Message"] = "It's evening here - Good Evening!";
        }
        return View();
    }

Jalankan aplikasi dan pesan ditampilkan berdasarkan waktu.

Injeksi tindakan dengan

memungkinkan menyuntikkan layanan langsung ke metode tindakan tanpa menggunakan injeksi konstruktor:

public IActionResult About([FromServices] IDateTime dateTime)
{
    ViewData["Message"] = $"Current server time: {dateTime.Now}";

    return View();
}

Pengaturan akses dari pengontrol

Mengakses pengaturan aplikasi atau konfigurasi dari dalam pengontrol adalah pola umum. Pola options yang dijelaskan dalam pola Options dalam ASP.NET Core adalah pendekatan yang disukai untuk mengelola pengaturan. Umumnya, jangan langsung menyuntikkan ke pengontrol.

Buat kelas yang mewakili opsi. Contohnya:

public class SampleWebSettings
{
    public string Title { get; set; }
    public int Updates { get; set; }
}

Tambahkan kelas konfigurasi ke koleksi layanan:

public void ConfigureServices(IServiceCollection services)
{
    services.AddSingleton<IDateTime, SystemDateTime>();
    services.Configure<SampleWebSettings>(Configuration);
    
    services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
}

Konfigurasikan aplikasi untuk membaca pengaturan dari file berformat JSON:

public class Program
{
    public static void Main(string[] args)
    {
        CreateWebHostBuilder(args).Build().Run();
    }

    public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
        WebHost.CreateDefaultBuilder(args)
        .ConfigureAppConfiguration((hostingContext, config) =>
        {
            config.AddJsonFile("samplewebsettings.json", 
                                optional: false,        // File is not optional.
                                reloadOnChange: false);
        })
        .UseStartup<Startup>();
}

Kode berikut meminta pengaturan dari kontainer layanan dan menggunakannya dalam metode :

public class SettingsController : Controller
{
    private readonly SampleWebSettings _settings;

    public SettingsController(IOptions<SampleWebSettings> settingsOptions)
    {
        _settings = settingsOptions.Value;
    }

    public IActionResult Index()
    {
        ViewData["Title"] = _settings.Title;
        ViewData["Updates"] = _settings.Updates;
        return View();
    }
}

Pengontrol sebagai layanan

Secara default, ASP.NET Core tidak mendaftarkan pengontrol sebagai layanan dalam kontainer DI. Runtime menggunakan DefaultControllerActivator untuk membuat instans pengontrol dan menyelesaikan layanan dari kontainer DI untuk parameter konstruktor, tetapi pengontrol itu sendiri tidak diselesaikan dari kontainer.

Panggilan mendaftarkan semua pengontrol sebagai layanan dalam kontainer DI:

public void ConfigureServices(IServiceCollection services)
{
    services.AddMvc().AddControllersAsServices();
}

Mendaftarkan pengontrol sebagai layanan memungkinkan:

  • Mencegat pembuatan pengontrol dengan kustom .
  • Menggunakan manajemen siklus hidup DI apa pun untuk kontroler.
  • Menyuntikkan layanan ke pengontrol menggunakan konstruktor terdaftar, karena kontainer DI memilih konstruktor.

Nota

Konfigurasikan sebelum memanggil . Lihat Berbagi pengontrol, tampilan, halaman Razor dan lainnya dengan Application Parts di ASP.NET Core untuk lebih jelasnya.

Sumber daya tambahan

  • Lihat logika pengontrol Test di ASP.NET Core untuk mempelajari cara membuat kode lebih mudah diuji dengan meminta dependensi secara eksplisit di pengontrol.

  • Ganti kontainer injeksi dependensi default dengan implementasi pihak ketiga.