Why it matters
these registrations compile, but fail at runtime when the container tries to activate the service.
Writing a ghost on the class register does not mean someone can actually show up for class.
DI018
registrations whose implementation type cannot be constructed by the DI container, such as abstract classes, interfaces, static classes, delegate types registered without a factory, default structs and enums, or concrete classes with no public constructors.
Why it matters
these registrations compile, but fail at runtime when the container tries to activate the service.
Writing a ghost on the class register does not mean someone can actually show up for class.
Install
dotnet add package DependencyInjection.Lifetime.Analyzers --version 2.18.24
README problem example
public interface IMyService { }
public sealed class BadPrivateCtorService : IMyService
{
private BadPrivateCtorService() { }
}
services.AddSingleton<IMyService, BadPrivateCtorService>();
README better pattern
public sealed class GoodConcreteService : IMyService { }
public readonly struct MyValueService { }
services.AddSingleton<IMyService, GoodConcreteService>();
// For delegate types, register with a factory expression:
services.AddSingleton<MyHandler>(sp => (msg) => Console.WriteLine(msg));
// Supply value types explicitly instead of asking the container to activate them:
services.AddSingleton(typeof(MyValueService), _ => new MyValueService());
Repo sample extraction
Sample app non-instantiable type
public abstract class BadAbstractService : IMyService { }
Sample app safe pattern
public class GoodConcreteService : IMyService { }
Related guides
More documentation