Autofac: Breaking change to RegisterInstance in 5.1.3 (compared to 5.1.2)

Created on 27 Apr 2020  ·  6Comments  ·  Source: autofac/Autofac

Is this for Autofac 5?

  • [x] Yes

This change in 5.1.3 causes the below minimal reproducible example to throw this exception:

Autofac.Core.DependencyResolutionException: An error occurred while attempting to automatically activate registration 'Activator = Classy (DelegateActivator), Services = [AutoActivate], Lifetime = Autofac.Core.Lifetime.CurrentScopeLifetime, Sharing = None, Ownership = OwnedByLifetimeScope'. See the inner exception for information on the source of the failure. ---> Autofac.Core.DependencyResolutionException: An exception was thrown while activating λ:ConsoleApp1.Classy. ---> Autofac.Core.Registration.ComponentNotRegisteredException: The requested service 'ConsoleApp1.Classy' has not been registered. To avoid this exception, either register a component to provide the service, check for service registration using IsRegistered(), or use the ResolveOptional() method to resolve an optional dependency.
  at at Autofac.ResolutionExtensions.ResolveService(IComponentContext context, Service service, IEnumerable`1 parameters)
  at at Autofac.ResolutionExtensions.Resolve(IComponentContext context, Type serviceType, IEnumerable`1 parameters)
  at at Autofac.ResolutionExtensions.Resolve[TService](IComponentContext context, IEnumerable`1 parameters)
  at at Autofac.ResolutionExtensions.Resolve[TService](IComponentContext context)
  at at Autofac.RegistrationExtensions.<>c__1`1.<RegisterInstance>b__1_1(IComponentContext c, IEnumerable`1 p)
  at at Autofac.Core.Activators.Delegate.DelegateActivator.ActivateInstance(IComponentContext context, IEnumerable`1 parameters)
  at at Autofac.Core.Resolving.InstanceLookup.CreateInstance(IEnumerable`1 parameters)
  --- End of inner exception stack trace ---
  at at Autofac.Core.Resolving.InstanceLookup.CreateInstance(IEnumerable`1 parameters)
  at at Autofac.Core.Resolving.InstanceLookup.Execute()
  at at Autofac.Core.Resolving.ResolveOperation.GetOrCreateInstance(ISharingLifetimeScope currentOperationScope, ResolveRequest request)
  at at Autofac.Core.Resolving.ResolveOperation.ResolveComponent(ResolveRequest request)
  at at Autofac.Core.Resolving.ResolveOperation.Execute(ResolveRequest request)
  at at Autofac.Core.Lifetime.LifetimeScope.ResolveComponent(ResolveRequest request)
  at at Autofac.Core.Container.ResolveComponent(ResolveRequest request)
  at at Autofac.Builder.StartableManager.StartStartableComponents(IDictionary`2 properties, IComponentContext componentContext)
  --- End of inner exception stack trace ---
  at at Autofac.Builder.StartableManager.StartStartableComponents(IDictionary`2 properties, IComponentContext componentContext)
  at at Autofac.ContainerBuilder.Build(ContainerBuildOptions options)
  at ConsoleApp1.Program.Main() in E:\Downloads\ConsoleApp1\Program.cs:22
using Autofac;

interface IFace
{}

class Classy : IFace
{}

class Program
{
    static void Main()
    {
        var builder = new ContainerBuilder();
        builder
            .RegisterInstance(new Classy())
            .As<IFace>()
            .OnActivated(e => { });
        using var container = builder.Build();
        var classy = container.Resolve<IFace>();
        GC.KeepAlive(classy);
    }
}

Honestly I'm not sure if this is a bug in Autofac or misuse on my part. It's easy enough for me to work around this by adding an .As<Classy>()/.AsSelf(), or by .RegisterInstance((IFace)new Classy()). But technically the revision 5.1.3 release causes this breaking change, and of course revisions aren't supposed to do that. What do you think?

Most helpful comment

No worries. I once released a version where I introduced an inadvertent memory leak where every lifetime scope and every disposable was held for the entire lifetime of the container. Whoops! Let me know when you top that one. ;)

All 6 comments

Hmmm. Looks like an unintentional side effect of PR #1104 to fix #1102. You shouldn't have to do any of those workarounds.

@alistairjevans do you have any ideas off the top of your head? If not, should we roll back #1104 temporarily to fix this?

Yes, it's because when I resolve the service during auto-activation I was using the instance's type rather than one of the services it registered. 🤦‍♂️

Just needs updating to resolve one of the actual services present in the registration data.

PR incoming.

PR approved and merged. Let me see about getting a 5.1.4 out shortly.

Thanks @tillig, my bad on this one.

No worries. I once released a version where I introduced an inadvertent memory leak where every lifetime scope and every disposable was held for the entire lifetime of the container. Whoops! Let me know when you top that one. ;)

You guys are the best. Thanks for the quick fix/release!

Was this page helpful?
0 / 5 - 0 ratings