Skip to content

NDLRCOR002: Plugin has constructor dependencies

Cause

A class implementing IServiceCollectionPlugin or IPostBuildServiceCollectionPlugin has a constructor with parameters but no public parameterless constructor.

Rule Description

Needlr plugin classes are instantiated by the framework before the dependency injection container is fully built. This means constructor injection is not available for plugin classes in the same way it is for regular services.

If a plugin has constructor parameters and no parameterless constructor, the framework may not be able to instantiate it, leading to runtime errors.

How to Fix

Option 1: Add a parameterless constructor

public class MyPlugin : IServiceCollectionPlugin
{
    public MyPlugin() { }

    public MyPlugin(ILogger logger) 
    { 
        // Optional: for use when instantiated via DI
    }

    public void Configure(ServiceCollectionPluginOptions options)
    {
        // Plugin configuration
    }
}

Option 2: Use IPostBuildServiceCollectionPlugin with service resolution

If you need access to services, use IPostBuildServiceCollectionPlugin which runs after the container is built:

public class MyPlugin : IPostBuildServiceCollectionPlugin
{
    public void Configure(PostBuildServiceCollectionPluginOptions options)
    {
        var logger = options.ServiceProvider.GetRequiredService<ILogger<MyPlugin>>();
        // Use the logger
    }
}

Option 3: Access services through the options parameter

public class MyPlugin : IServiceCollectionPlugin
{
    public void Configure(ServiceCollectionPluginOptions options)
    {
        // Register your service that needs dependencies
        options.Services.AddSingleton<MyService>();
    }
}

Detection

The rule matches plugin interfaces by symbol, so it also fires when the interface is inherited indirectly -- through a custom interface that extends a Needlr plugin interface, or through a base class that implements one -- and never fires for an unrelated interface that merely shares the same simple name in another namespace.

A base-list entry the compiler cannot resolve at all (for example a bare IServiceCollectionPlugin identifier while a using or package reference is still missing) is deliberately ignored, because its simple name alone cannot distinguish a Needlr plugin interface from any other. An unresolved but namespace-qualified entry such as NexusLabs.Needlr.IServiceCollectionPlugin is unambiguous and is still reported.

When to Suppress

Suppress this warning if:

  • The plugin is intentionally designed to be instantiated via DI after container construction
  • The plugin is abstract and constructor parameters are for derived classes
  • You are using a custom plugin factory that handles constructor injection
#pragma warning disable NDLRCOR002
public class MyCustomPlugin : IServiceCollectionPlugin
{
    public MyCustomPlugin(IPluginFactory factory) { }
    // ...
}
#pragma warning restore NDLRCOR002

See Also