Aracılığıyla paylaş


.NET'te bağımlılık eklemeyle ilgili temel bilgileri anlama

Bu makalede, ve karşılık gelen ServiceCollectionöğesini el ile oluşturan bir ServiceProvider .NET konsol uygulaması oluşturursunuz. Bağımlılık ekleme (DI) kullanarak hizmetleri kaydetmeyi ve çözmeyi öğrenirsiniz. Bu makalede, .NET'te DI'nin temellerini göstermek için Microsoft.Extensions.DependencyInjection NuGet paketi kullanılır.

Not

Bu makale, Genel Konak özelliklerinden yararlanmaz. Daha kapsamlı bir kılavuz için bkz . .NET'te bağımlılık eklemeyi kullanma.

Kullanmaya başlayın

Başlamak için DI.Basics adlı yeni bir .NET konsol uygulaması oluşturun. Konsol projesi oluşturmaya yönelik en yaygın yaklaşımlardan bazılarına aşağıdaki listeden başvurabilirsiniz:

Paket başvuruyu proje dosyasındaki Microsoft.Extensions.DependencyInjection dosyasına eklemeniz gerekir. Yaklaşımdan bağımsız olarak, projenin DI.Basics.csproj dosyasının aşağıdaki XML'sine benzediğinden emin olun:

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net8.0</TargetFramework>
    <ImplicitUsings>enable</ImplicitUsings>
    <Nullable>enable</Nullable>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="9.0.3" />
  </ItemGroup>

</Project>

Bağımlılık eklemeyle ilgili temel bilgiler

Bağımlılık ekleme, sabit kodlanmış bağımlılıkları kaldırmanıza ve uygulamanızı daha sürdürülebilir ve test edilebilir hale getirmenize olanak tanıyan bir tasarım desenidir. DI, sınıflar ve bağımlılıkları arasında Denetimin TersIni (IoC) elde etmeye yönelik bir tekniktir.

.NET'teki DI soyutlamaları Microsoft.Extensions.DependencyInjection.Abstractions NuGet paketinde tanımlanır:

.NET'te DI, hizmetleri ekleyip içinde IServiceCollectionyapılandırarak yönetilir. Hizmetler kaydedildikten sonra, yöntemi çağrılarak IServiceProvider bir BuildServiceProvider örnek oluşturulur. tüm IServiceProvider kayıtlı hizmetlerin kapsayıcısı görevi görür ve hizmetleri çözümlemek için kullanılır.

Örnek hizmetler oluşturma

Tüm hizmetler eşit şekilde oluşturulmaz. Bazı hizmetler, hizmet kapsayıcısının her aldığında (geçici) yeni bir örnek gerektirirken, diğerleri belirli kapsamda (kapsamlı hizmet) veya uygulamanın tüm ömrü boyunca paylaşılmalıdır (tekil hizmet). Hizmet ömrü hakkında daha fazla bilgi için bkz . Hizmet ömrü.

Benzer şekilde, bazı hizmetler yalnızca somut bir türü kullanıma sunarken, diğerleri bir arabirim ile uygulama türü arasında sözleşme olarak ifade edilir. Bu kavramların gösterilmesine yardımcı olmak için çeşitli hizmet varyasyonları oluşturursunuz.

IConsole.cs adlı yeni bir C# dosyası oluşturun ve aşağıdaki kodu ekleyin:

public interface IConsole
{
    void WriteLine(string message);
}

Bu dosya, tek bir yöntemi kullanıma sunan bir IConsole arabirim tanımlar. WriteLine Ardından, DefaultConsole.cs adlı yeni bir C# dosyası oluşturun ve aşağıdaki kodu ekleyin:

internal sealed class DefaultConsole : IConsole
{
    public bool IsEnabled { get; set; } = true;

    void IConsole.WriteLine(string message)
    {
        if (IsEnabled is false)
        {
            return;
        }

        Console.WriteLine(message);
    }
}

Yukarıdaki kod, arabirimin varsayılan uygulamasını IConsole temsil eder. yöntemi, WriteLine özelliğine göre IsEnabled konsola koşullu olarak yazar.

İpucu

Bir uygulamanın adlandırılması, geliştirme ekibinizin üzerinde anlaşmaya varması gereken bir seçimdir. Ön Default ek, bir arabirimin varsayılan uygulamasını gösteren yaygın bir kuraldır, ancak gerekli değildir.

Ardından bir IGreetingService.cs dosyası oluşturun ve aşağıdaki C# kodunu ekleyin:

public interface IGreetingService
{
    string Greet(string name);
}

Ardından DefaultGreetingService.cs adlı yeni bir C# dosyası ekleyin ve aşağıdaki kodu ekleyin:

internal sealed class DefaultGreetingService(
    IConsole console) : IGreetingService
{
    public string Greet(string name)
    {
        var greeting = $"Hello, {name}!";

        console.WriteLine(greeting);

        return greeting;
    }
}

Yukarıdaki kod, arabirimin varsayılan uygulamasını IGreetingService temsil eder. Hizmet uygulaması birincil oluşturucu parametresi olarak bir IConsole gerektirir. Greet yöntemi:

  • Verilen greetingbir name oluşturur.
  • WriteLine örnekte yöntemini IConsole çağırır.
  • greeting öğesini çağırana döndürür.

Oluşturulacak son hizmet FarewellService.cs dosyasıdır, devam etmeden önce aşağıdaki C# kodunu ekleyin:

public class FarewellService(IConsole console)
{
    public string SayGoodbye(string name)
    {
        var farewell = $"Goodbye, {name}!";

        console.WriteLine(farewell);

        return farewell;
    }
}

, FarewellService bir arabirimi değil somut bir türü temsil eder. Tüketiciler tarafından erişilebilir hale getirmek için olarak public bildirilmelidir. ve internalolarak bildirilen diğer hizmet uygulama türlerinden farklı olaraksealed, bu kod tüm hizmetlerin arabirim olması gerekmediğini gösterir. Ayrıca hizmet uygulamalarının devralmayı önlemek ve sealed derlemeye erişimi kısıtlamak için olabileceğini internal gösterir.

Sınıfını Program güncelleştirme

Program.cs dosyasını açın ve var olan kodu aşağıdaki C# koduyla değiştirin:

using Microsoft.Extensions.DependencyInjection;

// 1. Create the service collection.
var services = new ServiceCollection();

// 2. Register (add and configure) the services.
services.AddSingleton<IConsole>(
    implementationFactory: static _ => new DefaultConsole
    {
        IsEnabled = true
    });
services.AddSingleton<IGreetingService, DefaultGreetingService>();
services.AddSingleton<FarewellService>();

// 3. Build the service provider from the service collection.
var serviceProvider = services.BuildServiceProvider();

// 4. Resolve the services that you need.
var greetingService = serviceProvider.GetRequiredService<IGreetingService>();
var farewellService = serviceProvider.GetRequiredService<FarewellService>();

// 5. Use the services
var greeting = greetingService.Greet("David");
var farewell = farewellService.SayGoodbye("David");

Yukarıdaki güncelleştirilmiş kodda nasıl yapılır gösterilmektedir:

  • Yeni ServiceCollection bir örnek oluşturun.
  • içinde ServiceCollectionhizmetleri kaydedin ve yapılandırın:
    • IConsole, uygulama fabrikası aşırı yüklemesi kullanılarak, IsEnabled'nin trueolarak ayarlandığı bir DefaultConsole türü döndürür.
    • IGreetingService türüne karşılık gelen uygulama türüyle DefaultGreetingService eklenir.
    • beton FarewellService tip olarak eklenir.
  • 'den ServiceProvideröğesini ServiceCollection oluşturun.
  • IGreetingService ve FarewellService hizmetlerini çözün.
  • adlı Davidbir kişiyi selamlayıp veda etmek için çözümlenen hizmetleri kullanın.

öğesinin IsEnabledDefaultConsole özelliğini olarak falseGreetgüncelleştirirseniz ve SayGoodbye yöntemleri konsola gönderilen sonuçta elde edilen iletilere yazmayı atlar. Bunun gibi bir değişiklik, hizmetin IGreetingServiceFarewellService göstermeye yardımcı olur.

Bu hizmetlerin tümü tekil olarak kaydedilmiş olsa da, bu örnek için geçici veya kapsamı belirlenmiş hizmetleri aynı şekilde çalışır.

Önemli

Bu bağlantılı örnekte hizmet ömrü önemli değildir, ancak gerçek dünyada bir uygulamada her hizmetin ömrünü dikkatle dikkate almanız gerekir.

Örnek uygulamayı çalıştırma

Örnek uygulamayı çalıştırmak için Visual Studio, Visual Studio Code'da F5dotnet runveya terminalde komutunu çalıştırın. Uygulama tamamlandığında aşağıdaki çıkışı görmeniz gerekir:

Hello, David!
Goodbye, David!

Hizmet tanımlayıcıları

'a ServiceCollection hizmet eklemek için en yaygın olarak kullanılan API'ler şunlar gibi yaşam boyu adlandırılmış genel uzantı yöntemleridir:

  • AddSingleton<TService>
  • AddTransient<TService>
  • AddScoped<TService>

Bu yöntemler, bir ServiceDescriptor örnek oluşturan ve bunu öğesine ekleyen kolaylık yöntemleridir ServiceCollection. ServiceDescriptor, bir hizmeti hizmet türü, uygulama türü ve yaşam süresiyle açıklayan basit bir sınıftır. Uygulama fabrikalarını ve örneklerini de açıklayabilir.

içinde ServiceCollectionkaydettiğiniz hizmetlerin her biri için bunun yerine yöntemini doğrudan bir Add örnekle çağırabilirsinizServiceDescriptor. Aşağıdaki örnekleri değerlendirin:

services.Add(ServiceDescriptor.Describe(
    serviceType: typeof(IConsole),
    implementationFactory: static _ => new DefaultConsole
    {
        IsEnabled = true
    },
    lifetime: ServiceLifetime.Singleton));

Yukarıdaki kod, hizmetin içinde nasıl IConsole kaydedilildiğiyle ServiceCollectioneşdeğerdir. Add yöntemi, hizmeti açıklayan ServiceDescriptor bir IConsole örnek eklemek için kullanılır. Statik yöntem ServiceDescriptor.Describe çeşitli ServiceDescriptor oluşturuculara temsilciler. Hizmet için IGreetingService eşdeğer kodu göz önünde bulundurun:

services.Add(ServiceDescriptor.Describe(
    serviceType: typeof(IGreetingService),
    implementationType: typeof(DefaultGreetingService),
    lifetime: ServiceLifetime.Singleton));

Yukarıdaki kod, hizmeti hizmet türü, uygulama türü ve yaşam süresiyle açıklar IGreetingService . Son olarak, hizmet için FarewellService eşdeğer kodu göz önünde bulundurun:

services.Add(ServiceDescriptor.Describe(
    serviceType: typeof(FarewellService),
    implementationType: typeof(FarewellService),
    lifetime: ServiceLifetime.Singleton));

Yukarıdaki kod, somut FarewellService türü hem hizmet hem de uygulama türleri olarak açıklar. Hizmet bir tekil hizmet olarak kaydedilir.

Ayrıca bkz.