Poznámka:
Přístup k této stránce vyžaduje autorizaci. Můžete se zkusit přihlásit nebo změnit adresáře.
Přístup k této stránce vyžaduje autorizaci. Můžete zkusit změnit adresáře.
Tento článek popisuje registraci skupin služeb a služeb poskytovaných frameworkem. Poskytuje také podrobnosti o metodách rozšíření registrace služby, které poskytuje .NET.
Registrace skupin služeb prostřednictvím rozšiřovacích metod
.NET používá konvenci pro registraci skupiny souvisejících služeb. Konvence spočívá v použití jedné Add{GROUP_NAME} rozšiřující metody k registraci všech služeb vyžadovaných funkcí architektury. Například AddOptions metoda rozšíření zaregistruje všechny služby potřebné pro použití možností.
Služby poskytované frameworkem
Pokud používáte některý z dostupných vzorů hostitele nebo tvůrce aplikací, použijí se výchozí hodnoty a rozhraní zaregistruje služby. Představte si některé z nejoblíbenějších vzorů pro hostitele a tvůrce aplikací:
- Host.CreateDefaultBuilder()
- Host.CreateApplicationBuilder()
- WebHost.CreateDefaultBuilder()
- WebApplication.CreateBuilder()
- WebAssemblyHostBuilder.CreateDefault
- MauiApp.CreateBuilder
Po vytvoření builderu z některého z těchto rozhraní API IServiceCollection má služby definované frameworkem, v závislosti na tom, jak jste hostitele nakonfigurovali. Pro aplikace založené na šablonách .NET by architektura mohla zaregistrovat stovky služeb.
Následující tabulka uvádí malou ukázku těchto služeb registrovaných rámcem.
| Typ služby | Životnost |
|---|---|
| Microsoft.Extensions.DependencyInjection.IServiceScopeFactory | Singleton |
| IHostApplicationLifetime | Singleton |
| Microsoft.Extensions.Logging.ILogger<TCategoryName> | Singleton |
| Microsoft.Extensions.Logging.ILoggerFactory | Singleton |
| Microsoft.Extensions.ObjectPool.ObjectPoolProvider | Singleton |
| Microsoft.Extensions.Options.IConfigureOptions<TOptions> | Transient |
| Microsoft.Extensions.Options.IOptions<TOptions> | Singleton |
| System.Diagnostics.DiagnosticListener | Singleton |
| System.Diagnostics.DiagnosticSource | Singleton |
Metody registrace
Architektura poskytuje metody rozšíření registrace služeb, které jsou užitečné v konkrétních scénářích:
| Metoda | Automatické odstranění objektů | Více implementací | Předávání args |
|---|---|---|---|
Add{LIFETIME}<{SERVICE}, {IMPLEMENTATION}>()Příklad: services.AddSingleton<IMyDep, MyDep>(); |
Ano | Ano | Ne |
Add{LIFETIME}<{SERVICE}>(sp => new {IMPLEMENTATION})Examples: services.AddSingleton<IMyDep>(sp => new MyDep());services.AddSingleton<IMyDep>(sp => new MyDep(99)); |
Ano | Ano | Ano |
Add{LIFETIME}<{IMPLEMENTATION}>()Příklad: services.AddSingleton<MyDep>(); |
Ano | Ne | Ne |
AddSingleton<{SERVICE}>(new {IMPLEMENTATION})Examples: services.AddSingleton<IMyDep>(new MyDep());services.AddSingleton<IMyDep>(new MyDep(99)); |
Ne | Ano | Ano |
AddSingleton(new {IMPLEMENTATION})Examples: services.AddSingleton(new MyDep());services.AddSingleton(new MyDep(99)); |
Ne | Ne | Ano |
Další informace o likvidaci typu najdete v tématu Likvidace služeb.
Registrace služby pouze s typem implementace je ekvivalentní registraci této služby se stejným typem implementace a služby. Představte si například následující kód:
services.AddSingleton<ExampleService>();
Toto je ekvivalentní registraci služby spolu s její implementací stejného typu.
services.AddSingleton<ExampleService, ExampleService>();
Tato ekvivalence je důvod, proč není možné zaregistrovat více implementací služby pomocí metod, které nepoužívají explicitní typ služby. Tyto metody mohou zaregistrovat více instancí služby , ale všechny mají typ implementace stejný.
Libovolnou metodu registrace služby lze použít k registraci více instancí služby stejného typu služby. V následujícím příkladu je AddSingleton dvakrát voláno jako typ služby IMessageWriter. Druhé volání AddSingleton nahrazuje předchozí volání, když je vyřešeno jako IMessageWriter, a přidává k předchozímu volání, když jsou prostřednictvím IEnumerable<IMessageWriter> vyřešeny více služeb. Služby se zobrazují v pořadí, v jakém byly zaregistrovány při řešení prostřednictvím IEnumerable<{SERVICE}>.
using ConsoleDI.IEnumerableExample;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
HostApplicationBuilder builder = Host.CreateApplicationBuilder(args);
builder.Services.AddSingleton<IMessageWriter, ConsoleMessageWriter>();
builder.Services.AddSingleton<IMessageWriter, LoggingMessageWriter>();
builder.Services.AddSingleton<ExampleService>();
using IHost host = builder.Build();
_ = host.Services.GetService<ExampleService>();
await host.RunAsync();
Předchozí vzorový zdrojový kód registruje dvě implementace IMessageWriter.
using System.Diagnostics;
namespace ConsoleDI.IEnumerableExample;
public sealed class ExampleService
{
public ExampleService(
IMessageWriter messageWriter,
IEnumerable<IMessageWriter> messageWriters)
{
Trace.Assert(messageWriter is LoggingMessageWriter);
var dependencyArray = messageWriters.ToArray();
Trace.Assert(dependencyArray[0] is ConsoleMessageWriter);
Trace.Assert(dependencyArray[1] is LoggingMessageWriter);
}
}
Definuje ExampleService dva parametry konstruktoru: jeden IMessageWriter a IEnumerable<IMessageWriter>. Jedinou IMessageWriter implementací je poslední registrace, zatímco IEnumerable<IMessageWriter> představuje všechny registrované implementace.
Architektura také poskytuje TryAdd{LIFETIME} rozšiřující metody, které zaregistrují službu pouze v případě, že ještě není zaregistrovaná implementace.
V následujícím příkladu volání AddSingleton registruje ConsoleMessageWriter jako implementaci pro IMessageWriter. Volání TryAddSingleton nemá žádný účinek, protože IMessageWriter již má zaregistrovanou implementaci:
services.AddSingleton<IMessageWriter, ConsoleMessageWriter>();
services.TryAddSingleton<IMessageWriter, LoggingMessageWriter>();
Nemá TryAddSingleton žádný vliv, protože už byl přidán a pokus selže. Tento ExampleService výraz potvrzuje následující:
public class ExampleService
{
public ExampleService(
IMessageWriter messageWriter,
IEnumerable<IMessageWriter> messageWriters)
{
Trace.Assert(messageWriter is ConsoleMessageWriter);
Trace.Assert(messageWriters.Single() is ConsoleMessageWriter);
}
}
Další informace najdete tady:
Metody TryAddEnumerable(ServiceDescriptor) registrují službu pouze v případě, že ještě neexistuje implementace stejného typu. Více služeb je řešeno skrze IEnumerable<{SERVICE}>. Při registraci služeb přidejte instanci, pokud ještě nebyl přidán jeden ze stejných typů. Autoři knihoven používají TryAddEnumerable aby zabránili registraci více kopií implementace v kontejneru.
V následujícím příkladu první volání TryAddEnumerable registruje MessageWriter jako implementaci pro IMessageWriter1. Druhý hovor zaregistruje MessageWriter pro IMessageWriter2. Třetí volání nemá žádný účinek, protože IMessageWriter1 již má zaregistrovanou implementaci MessageWriter:
public interface IMessageWriter1 { }
public interface IMessageWriter2 { }
public class MessageWriter : IMessageWriter1, IMessageWriter2
{
}
services.TryAddEnumerable(ServiceDescriptor.Singleton<IMessageWriter1, MessageWriter>());
services.TryAddEnumerable(ServiceDescriptor.Singleton<IMessageWriter2, MessageWriter>());
services.TryAddEnumerable(ServiceDescriptor.Singleton<IMessageWriter1, MessageWriter>());
Registrace služby je nezávislá na objednávce s výjimkou registrace více implementací stejného typu.
IServiceCollection je kolekce ServiceDescriptor objektů. Následující příklad ukazuje, jak zaregistrovat službu vytvořením a přidáním ServiceDescriptor:
string secretKey = Configuration["SecretKey"];
var descriptor = new ServiceDescriptor(
typeof(IMessageWriter),
_ => new DefaultMessageWriter(secretKey),
ServiceLifetime.Transient);
services.Add(descriptor);
Integrované Add{LIFETIME} metody používají stejný přístup. Podívejte se například na zdrojový kód AddScoped.