microsoft/migrating-autofac-to-dotnet-di
> Removes Autofac entirely and migrates to ASP.NET Core built-in DI by mapping container registrations, lifetimes, and module patterns. Use when upgrading .NET projects that reference Autofac packages, when converting ContainerBuilder registrations, or when replacing Autofac modules with IServiceCollection extensions. Triggers for "replace Autofac", "remove Autofac", "migrate to built-in DI", "convert dependency injection", Autofac.Extensions.DependencyInjection, RegisterType, InstancePerLifetimeScope, and ContainerBuilder references in C# or VB.NET projects.
npx skills add https://github.com/microsoft/upgrade-agent-plugins --skill migrating-autofac-to-dotnet-di
Converts Autofac DI registrations to ASP.NET Core's built-in IServiceCollection pattern. The built-in container covers most registration scenarios; assembly scanning requires the Scrutor NuGet package.
> Related skill: If the goal is to keep Autofac but modernize its integration with ASP.NET Core, use integrating-autofac-with-dotnet instead.
Before starting, confirm the project actually uses Autofac. Search for Autofac NuGet references and ContainerBuilder usage. If none found, inform the user there is nothing to migrate.
Migration Progress:
- [ ] Step 1: Locate Autofac registrations
- [ ] Step 2: Document all registrations
- [ ] Step 3: Remove Autofac code
- [ ] Step 4: Remove Autofac packages
- [ ] Step 5: Create registration helper
- [ ] Step 6: Wire into Program.cs
- [ ] Step 7: Build and verify
Find ContainerBuilder setup code (check global.asax.cs, Startup.cs, or Autofac module classes).
Record each service registration and its lifetime scope before removing anything.
Delete the container builder code that will be replaced.
Remove Autofac, Autofac.Extensions.DependencyInjection, and any other Autofac-related NuGet packages.
Add a static helper method that registers all services on IServiceCollection, using the lifetime mapping table below.
Call the helper method from Program.cs, passing builder.Services.
Build the project, fix any remaining Autofac references, confirm no regressions.
| Autofac | ASP.NET Core DI | Notes |
|---------|-----------------|-------|
| InstancePerDependency() | AddTransient<T>() | Default Autofac lifetime |
| InstancePerLifetimeScope() | AddScoped<T>() | One per request in web apps |
| InstancePerRequest() | AddScoped<T>() | Web-specific alias for scoped |
| SingleInstance() | AddSingleton<T>() | |
| RegisterInstance(obj) | AddSingleton(obj) | |
| RegisterAssemblyTypes(...) | services.Scan(...) | Requires Scrutor package |
Interface registration:
// Autofac
builder.RegisterType<MyService>().As<IMyService>().InstancePerLifetimeScope();
// Built-in DI
services.AddScoped<IMyService, MyService>();
Registration helper pattern — isolates DI setup for testability and keeps Program.cs clean:
// In Program.cs
var builder = WebApplication.CreateBuilder(args);
RegisterServices(builder.Services, builder.Configuration);
var app = builder.Build();
static void RegisterServices(IServiceCollection services, IConfiguration configuration)
{
services.AddScoped<IMyService, MyService>();
services.AddSingleton<IMyOtherService, MyOtherService>();
}
InstancePerDependency (transient), so unspecified lifetimes should map to AddTransient.RegisterAssemblyTypes, add the Scrutor NuGet package (dotnet add package Scrutor) and use services.Scan(...) to replicate the behavior.ContainerBuilder or Autofac namespace references remainTake microsoft/migrating-autofac-to-dotnet-di from the repository into ~/.claude/skills for personal
use, or into .claude/skills inside a project.
The agent identifies a skill by the name field in its header. Two skills with the
same name cannot sit side by side — one of them will be ignored.