### Install ServiceLocator Package Source: https://github.com/alzuma/servicelocator/blob/master/README.md Use the dotnet CLI to add the ServiceLocator package to your project. ```bash dotnet add package ServiceLocator ``` -------------------------------- ### Singleton Service Lifetime Example Source: https://github.com/alzuma/servicelocator/blob/master/README.md Register a service with `ServiceLifetime.Singleton` to ensure a single instance is shared across the entire application lifetime. ```csharp [Service(ServiceLifetime.Singleton)] public class ConfigurationService : IConfigurationService { // Single instance for entire application } ``` -------------------------------- ### Transient Service Lifetime Example Source: https://github.com/alzuma/servicelocator/blob/master/README.md Register a service with `ServiceLifetime.Transient` to ensure a new instance is created every time it is requested or injected. ```csharp [Service(ServiceLifetime.Transient)] public class TemporaryService : ITemporaryService { // New instance every time it's injected } ``` -------------------------------- ### Scoped Service Lifetime Example Source: https://github.com/alzuma/servicelocator/blob/master/README.md Register a service with `ServiceLifetime.Scoped` to ensure a new instance is created for each HTTP request in web applications. ```csharp [Service(ServiceLifetime.Scoped)] public class RequestService : IRequestService { // New instance per HTTP request } ``` -------------------------------- ### Enumerate All Services (Keyed and Non-Keyed) Source: https://github.com/alzuma/servicelocator/blob/master/README.md Resolve all registered services, including both keyed and non-keyed implementations, using `IEnumerable`. This allows for iterating through all available services of a given type. ```csharp // Enumerate all (both keyed and non-keyed) app.MapGet("/cache/all/{key}", (string key, IEnumerable caches) => { return caches.Select(c => c.Get(key)); // Returns: ["Default: test", "Fast: test"] }); ``` -------------------------------- ### Decorate Services with [Service] Attribute Source: https://github.com/alzuma/servicelocator/blob/master/README.md Decorate your service classes with the [Service] attribute to enable automatic registration. Specify the desired service lifetime. ```csharp using Microsoft.Extensions.DependencyInjection; using ServiceLocator; public interface IUserService { User GetUser(int id); } [Service(ServiceLifetime.Scoped)] public class UserService : IUserService { public User GetUser(int id) => new User { Id = id }; } ``` -------------------------------- ### Register and Resolve Keyed Services in C# Source: https://context7.com/alzuma/servicelocator/llms.txt Use the Key property in the [Service] attribute to register multiple implementations of an interface, then resolve them using [FromKeyedServices]. ```csharp using Microsoft.Extensions.DependencyInjection; using ServiceLocator; public interface ICache { string Get(string key); } [Service(ServiceLifetime.Singleton, Key = "big")] public class BigCache : ICache { public string Get(string key) => $"Big cache: {key}"; } [Service(ServiceLifetime.Singleton, Key = "small")] public class SmallCache : ICache { public string Get(string key) => $"Small cache: {key}"; } // Resolve specific implementation by key using [FromKeyedServices] app.MapGet("/api/cache/big/{key}", ( string key, [FromKeyedServices("big")] ICache cache) => { return Results.Ok(cache.Get(key)); // Returns: "Big cache: {key}" }); app.MapGet("/api/cache/small/{key}", ( string key, [FromKeyedServices("small")] ICache cache) => { return Results.Ok(cache.Get(key)); // Returns: "Small cache: {key}" }); ``` -------------------------------- ### Enumerate All Service Implementations Source: https://github.com/alzuma/servicelocator/blob/master/README.md Resolve all registered implementations of an interface, including keyed services, by injecting `IEnumerable`. ```csharp app.MapGet("/cache/all/{key}", ( string key, IEnumerable caches) => { return caches.Select(c => c.Get(key)); }); // Returns: ["Redis: test", "Memory: test"] ``` -------------------------------- ### Register Services with AddServiceLocator Source: https://context7.com/alzuma/servicelocator/llms.txt Use the AddServiceLocator extension method to scan an assembly for classes decorated with the [Service] attribute. ```csharp using ServiceLocator; var builder = WebApplication.CreateBuilder(args); // Scan the assembly containing Program for all [Service] decorated classes builder.Services.AddServiceLocator(); var app = builder.Build(); app.Run(); ``` -------------------------------- ### Register Keyed Services Source: https://github.com/alzuma/servicelocator/blob/master/README.md Register multiple implementations of the same interface by assigning a unique key to each using the `Key` property in the [Service] attribute. ```csharp public interface ICache { string Get(string key); } [Service(ServiceLifetime.Singleton, Key = "redis")] public class RedisCache : ICache { public string Get(string key) => $ ``` ```csharp [Service(ServiceLifetime.Singleton, Key = "memory")] public class MemoryCache : ICache { public string Get(string key) => $"Memory: {key}"; } ``` -------------------------------- ### Resolve Services via Dependency Injection Source: https://github.com/alzuma/servicelocator/blob/master/README.md After registration, services can be resolved and used through standard dependency injection in your application components. ```csharp app.MapGet("/user/{id}", (int id, IUserService userService) => { return userService.GetUser(id); }); app.Run(); ``` -------------------------------- ### Register and Resolve Keyed Service with Enum Key Source: https://github.com/alzuma/servicelocator/blob/master/README.md Register a service with an enum key using the [Service] attribute and resolve it using [FromKeyedServices]. This enables specific instance retrieval based on the enum value. ```csharp [Service(ServiceLifetime.Singleton, Key = CacheType.Primary)] public class PrimaryCache : ICache { // ... } ``` ```csharp // Resolve by enum app.MapGet("/cache/primary", ([FromKeyedServices(CacheType.Primary)] ICache cache) => { return cache.Get("data"); }); ``` -------------------------------- ### Enumerate Service Implementations in C# Source: https://context7.com/alzuma/servicelocator/llms.txt Inject IEnumerable to retrieve all registered implementations of an interface, including keyed and non-keyed services. ```csharp using Microsoft.Extensions.DependencyInjection; using ServiceLocator; public interface ISameService { string GetName(); } [Service(ServiceLifetime.Scoped)] public class SameServiceOne : ISameService { public string GetName() => "SameServiceOne"; } [Service(ServiceLifetime.Scoped)] public class SameServiceTwo : ISameService { public string GetName() => "SameServiceTwo"; } // Inject all implementations via IEnumerable app.MapGet("/api/services", (IEnumerable services) => { var names = services.Select(s => s.GetName()).ToList(); return Results.Ok(names); // Returns: ["SameServiceOne", "SameServiceTwo"] }); // Also works with keyed services - all keyed implementations are enumerable app.MapGet("/api/caches/all/{key}", (string key, IEnumerable caches) => { var results = caches.Select(c => c.Get(key)).ToList(); return Results.Ok(results); // Returns: ["Big cache: {key}", "Small cache: {key}"] }); ``` -------------------------------- ### Use Enum Keys for Keyed Services in C# Source: https://context7.com/alzuma/servicelocator/llms.txt Use enums as keys for keyed services to ensure type safety and avoid string-based typos. ```csharp using Microsoft.Extensions.DependencyInjection; using Microsoft.AspNetCore.Mvc; using ServiceLocator; public enum CacheType { Primary, Secondary, Fallback } public interface ICache { string Get(string key); } [Service(ServiceLifetime.Singleton, Key = CacheType.Primary)] public class PrimaryCache : ICache { public string Get(string key) => $"Primary: {key}"; } [Service(ServiceLifetime.Singleton, Key = CacheType.Secondary)] public class SecondaryCache : ICache { public string Get(string key) => $"Secondary: {key}"; } [Service(ServiceLifetime.Singleton, Key = CacheType.Fallback)] public class FallbackCache : ICache { public string Get(string key) => $"Fallback: {key}"; } // Resolve by enum key - type-safe, no string typos app.MapGet("/cache/primary/{key}", ( string key, [FromKeyedServices(CacheType.Primary)] ICache cache) => { return cache.Get(key); // Returns: "Primary: {key}" }); app.MapGet("/cache/fallback/{key}", ( string key, [FromKeyedServices(CacheType.Fallback)] ICache cache) => { return cache.Get(key); // Returns: "Fallback: {key}" }); ``` -------------------------------- ### Update Target Framework to .NET 9.0 Source: https://github.com/alzuma/servicelocator/blob/master/README.md Update the project's target framework to .NET 9.0 as required by ServiceLocator v2.0.0. This is a necessary step for compatibility. ```xml net9.0 ``` -------------------------------- ### Register Mixed Keyed and Non-Keyed Services Source: https://github.com/alzuma/servicelocator/blob/master/README.md Register both non-keyed and keyed services within the same application. Non-keyed services are resolved traditionally, while keyed services use a specific key for resolution. ```csharp // Non-keyed service (traditional registration) [Service(ServiceLifetime.Scoped)] public class DefaultCache : ICache { public string Get(string key) => $ ``` ```csharp // Keyed services [Service(ServiceLifetime.Scoped, Key = "fast")] public class FastCache : ICache { public string Get(string key) => $ ``` -------------------------------- ### Resolve Non-Keyed and Keyed Services Source: https://github.com/alzuma/servicelocator/blob/master/README.md Demonstrates resolving both a non-keyed service and a keyed service using their respective resolution methods. Non-keyed services are resolved directly by their interface, while keyed services require the specific key. ```csharp // Resolve non-keyed service app.MapGet("/cache/default/{key}", (string key, ICache cache) => { return cache.Get(key); // Gets DefaultCache }); ``` ```csharp // Resolve keyed service app.MapGet("/cache/fast/{key}", ( string key, [FromKeyedServices("fast")] ICache cache) => { return cache.Get(key); // Gets FastCache }); ``` -------------------------------- ### Register ServiceLocator in Application Source: https://github.com/alzuma/servicelocator/blob/master/README.md Call the `AddServiceLocator()` extension method on the service collection to automatically register all services decorated with the [Service] attribute from the specified assembly. ```csharp var builder = WebApplication.CreateBuilder(args); // Automatically register all services with [Service] attribute // from the assembly containing Program builder.Services.AddServiceLocator(); var app = builder.Build(); ``` -------------------------------- ### Register Multiple Interface Implementations Source: https://github.com/alzuma/servicelocator/blob/master/README.md Register multiple classes that implement the same interface. These can be resolved individually or as a collection. ```csharp public interface INotificationService { void Notify(string message); } [Service(ServiceLifetime.Scoped)] public class EmailNotificationService : INotificationService { public void Notify(string message) => SendEmail(message); } [Service(ServiceLifetime.Scoped)] public class SmsNotificationService : INotificationService { public void Notify(string message) => SendSms(message); } // Inject all implementations app.MapPost("/notify", (string message, IEnumerable notifiers) => { foreach (var notifier in notifiers) { notifier.Notify(message); } }); ``` -------------------------------- ### Define Singleton Service Source: https://context7.com/alzuma/servicelocator/llms.txt Register a service with ServiceLifetime.Singleton to share a single instance across the entire application lifetime. ```csharp using Microsoft.Extensions.DependencyInjection; using ServiceLocator; public interface ISingletonService { void AddValue(string value); List GetValues(); } [Service(ServiceLifetime.Singleton)] public class SingletonService : ISingletonService { private readonly List _values = new(); public void AddValue(string value) => _values.Add(value); public List GetValues() => _values; } // Usage - singleton persists values across all requests app.MapGet("/api/singleton", (ISingletonService service) => { service.AddValue("new-value"); return Results.Ok(service.GetValues()); // Accumulates across requests }); ``` -------------------------------- ### Add ServiceLocator Package Source: https://github.com/alzuma/servicelocator/blob/master/README.md Update the ServiceLocator package to version 2.0.3 using the .NET CLI. This command adds or updates the specified package in the project. ```bash dotnet add package ServiceLocator --version 2.0.3 ``` -------------------------------- ### Resolve Services by Concrete Type in C# Source: https://context7.com/alzuma/servicelocator/llms.txt Services are registered by both interface and concrete type, allowing direct injection of the implementation class. ```csharp using Microsoft.Extensions.DependencyInjection; using ServiceLocator; [Service(ServiceLifetime.Scoped)] public class ScopedService : IScopedService { private readonly List _values = new(); public void AddValue(string value) => _values.Add(value); public List GetValues() => _values; } // Inject by interface app.MapGet("/api/by-interface", (IScopedService service) => { service.AddValue("via interface"); return Results.Ok(service.GetValues()); }); // Inject by concrete type app.MapGet("/api/by-type", (ScopedService service) => { service.AddValue("via concrete type"); return Results.Ok(service.GetValues()); }); ``` -------------------------------- ### Resolve Keyed Services Source: https://github.com/alzuma/servicelocator/blob/master/README.md Resolve a specific implementation of an interface by using the `[FromKeyedServices]` attribute with the corresponding key. ```csharp app.MapGet("/cache/redis/{key}", ( string key, [FromKeyedServices("redis")] ICache cache) => { return cache.Get(key); }); app.MapGet("/cache/memory/{key}", ( string key, [FromKeyedServices("memory")] ICache cache) => { return cache.Get(key); }); ``` -------------------------------- ### Define Transient Service Source: https://context7.com/alzuma/servicelocator/llms.txt Register a service with ServiceLifetime.Transient to create a new instance every time it is requested. ```csharp using Microsoft.Extensions.DependencyInjection; using ServiceLocator; public interface ITransientService { void AddValue(string value); List GetValues(); } [Service(ServiceLifetime.Transient)] public class TransientService : ITransientService { private readonly List _values = new(); public void AddValue(string value) => _values.Add(value); public List GetValues() => _values; } // Usage - each resolution gets a fresh instance app.MapGet("/api/transient", (IServiceProvider sp) => { var service1 = sp.GetRequiredService(); service1.AddValue("value1"); var service2 = sp.GetRequiredService(); return Results.Ok(service2.GetValues()); // Returns: [] (empty, new instance) }); ``` -------------------------------- ### Define Enum for Cache Types Source: https://github.com/alzuma/servicelocator/blob/master/README.md Define an enum to be used as a key for keyed services. This allows for type-safe resolution of services. ```csharp public enum CacheType { Primary, Secondary, Fallback } ``` -------------------------------- ### Define Scoped Service Source: https://context7.com/alzuma/servicelocator/llms.txt Register a service with ServiceLifetime.Scoped to ensure one instance per request scope. ```csharp using Microsoft.Extensions.DependencyInjection; using ServiceLocator; public interface IScopedService { void AddValue(string value); List GetValues(); } [Service(ServiceLifetime.Scoped)] public class ScopedService : IScopedService { private readonly List _values = new(); public void AddValue(string value) => _values.Add(value); public List GetValues() => _values; } // Usage in minimal API - same instance within request scope app.MapGet("/api/scoped", (IServiceProvider sp) => { var service1 = sp.GetRequiredService(); service1.AddValue("value1"); var service2 = sp.GetRequiredService(); service2.AddValue("value2"); return Results.Ok(service2.GetValues()); // Returns: ["value1", "value2"] }); ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.