Search code examples
c#.netautofacobsolete

Configure autofac to ignore constructors marked as obsolete


Is it possible to easily configure autofac so it will only resolve using non-obsolete constructors?

eg for a class with a helper constructor for non-DI code,

public class Example {

    public Example(MyService service) {
        // ...
    }

    [Obsolete]
    public Example() {
        service = GetFromServiceLocator<MyService>();
        // ...
    }
}

// ....

var builder = new ContainerBuilder();
builder.RegisterType<Example>();
// no MyService defined.
var container = builder.Build();

// this should throw an exception
var example = container.Resolve<Example>();

asking autofac to resolve Example if we haven't registered MyService, should fail.


Solution

  • I don't believe there is an out of the box way to configure Autofac to ignore Obsolete constructors. However, Autofac is so good, there is always a way to get it done :) Here are two options:

    Option 1. Tell Autofac which Constructor to use

    Do this using the UsingConstructor registration extension method.

    builder.RegisterType<Example>().UsingConstructor(typeof(MyService));
    

    Option 2. Provide a custom IConstructorFinder to FindConstructorsWith

    Autofac has a registration extension method called FindConstructorsWith. You can pass a custom IConstructorFinder to one of the two overloads. You could write a simple IConstructorFinder called NonObsoleteConstructorFinder that will only return constructors without the Obsolete attribute.

    I have written this class and added a working version of your sample. You can view the full code and use it as inspiration. IMO option this is the more elegant option. I have added it to my AutofacAnswers project on GitHub.

    Note: The other overload takes BindingFlags. I don't think you can specify attribute requirements using BindingFlags. However, you may want to check that.