How to use Scrutor in ASP.NET Core
By FoxLearn 1/4/2025 2:38:44 AM 78
Dependency injection (DI) promotes loose coupling, testability, and maintainability by allowing you to change implementations without altering the classes or interfaces that use them.
Without dependency injection, changes in dependent objects require modifying the object that uses them, making unit testing difficult. With DI, dependent objects are injected at runtime, avoiding the need for internal construction and simplifying testing.
Scrutor is not a DI container but a library that offers a fluent API for service registration based on conventions, using ASP.Net Core's built-in DI container. For more advanced DI features, third-party containers like AutoFac, Windsor, StructureMap, Ninject, and DryIoc can be used. Scrutor primarily extends ASP.Net Core's DI with assembly scanning and decoration capabilities.
Create a new ASP.Net Core project in Visual Studio and then install Scrutor from NuGet using the NuGet Package Manager or Console.
Scanning assemblies using Scrutor in ASP.NET Core
The Scrutor API extends the IServiceCollection
interface with two methods: scan
and decorate
.
The scan
method searches an assembly for types that match a service to be registered, while decorate
is used to decorate an existing service instance.
In this post, the focus is on the scan
method, which involves defining a selector, registration strategy, services, and their lifetimes. Scrutor scans assemblies to find types that match the convention and registers them with ASP.Net Core's DI container. Without Scrutor, you would manually register services like IService1
, IService2
, and IService3
with corresponding implementations.
services.AddScoped<IService1, Service1>(); services.AddScoped<IService2, Service2>(); services.AddScoped<IService3, Service3>();
Registering services using Scrutor in ASP.NET Core
The code snippet shows how to simplify service registration in the ConfigureServices
method of the Startup
class by using Scrutor's assembly scanning capabilities.
public void ConfigureServices(IServiceCollection services) { services.Scan(scan => scan.FromCallingAssembly() .AddClasses() .AsMatchingInterface()); services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1); }
You can also explicitly specify the types in the scan
method.
For instance, if you have two services, ServiceA
and ServiceB
, you can register them as transient services like this:
services.AddTransient<ServiceA>(); services.AddTransient<ServiceB>();
Alternatively, you can explicitly list the types in the scan
method and register them with a transient lifetime:
services.Scan(scan => scan .AddTypes<ServiceA, ServiceB>() .AsSelf() .WithTransientLifetime());
Another variation allows you to pass a type to Scrutor, which will then find all classes in the assembly containing that type.
For example:
services.Scan(scan => scan .FromAssemblyOf<IDataService>() .AddClasses() .AsSelf() .WithTransientLifetime());
Scrutor is an open-source framework that enhances the default Microsoft.Extensions.DependencyInjection
DI container in ASP.Net Core by adding scanning capabilities.
- Content Negotiation in Web API
- How to fix 'InvalidOperationException: Scheme already exists: Bearer'
- How to fix System.InvalidOperationException: Scheme already exists: Identity.Application
- Add Thread ID to the Log File using Serilog
- Handling Exceptions in .NET Core API with Middleware
- InProcess Hosting in ASP.NET Core
- Limits on ThreadPool.SetMinThreads and SetMaxThreads
- Controlling DateTime Format in JSON Output with JsonSerializerOptions