Upgrading from Autofac 5.x to 6.x
In the change from Autofac 5.x to 6.x, the internals of Autofac went through a major overhaul; specifically, changing to a resolve pipeline for executing a resolve.
While there should not be any breaking behavioral changes, there are some method signature and interface member changes you may need to be aware of.
We have gone out of our way to try and reduce the number of breaking changes, so the breaks are generally limited to more advanced usage scenarios that most users shouldn’t run into.
If you have implemented a custom
IConstructorSelectorto pass to theUsingConstructorregistration method, you will need to update your implementation to useBoundConstructorinstead ofConstructorParameterBinding. The newBoundConstructortype exposes similar properties (including theTargetConstructor):// v5.x ConstructorParameterBinding SelectConstructorBinding(ConstructorParameterBinding[] constructorBindings, IEnumerable<Parameter> parameters); // v6.x BoundConstructor SelectConstructorBinding(BoundConstructor[] constructorBindings, IEnumerable<Parameter> parameters);
If you have implemented a custom registration source you will need to update the
IRegistrationSource.RegistrationsFormethod.// 5.x IEnumerable<IComponentRegistration> RegistrationsFor(Service service, Func<Service, IEnumerable<IComponentRegistration>> registrationAccessor); // 6.x IEnumerable<IComponentRegistration> RegistrationsFor(Service service, Func<Service, IEnumerable<ServiceRegistration>> registrationAccessor);
The
registrationAccessorparameter is a callback that, given a service, will return the set of registrations available for that service.In 6.x, the return type of this callback was changed from
IEnumerable<IComponentRegistration>toIEnumerable<ServiceRegistration>.A
ServiceRegistrationencapsulates the registration (via theRegistrationproperty of the type), but also exposes the resolve pipeline Autofac needs in order to resolve a registration.If you have implemented your own
IInstanceActivator(instead of relying on the built-in Autofac ones), then you will need to update it; instead of anActivateInstancemethod to return an instance, instead the activator must implement aConfigurePipeline, which allows the Activator to add its own middleware to the resolve pipeline.// 5.x public interface IInstanceActivator : IDisposable { object ActivateInstance(IComponentContext context, IEnumerable<Parameter> parameters); Type LimitType { get; } } // 6.x public interface IInstanceActivator : IDisposable { void ConfigurePipeline(IComponentRegistryServices componentRegistryServices, IResolvePipelineBuilder pipelineBuilder); Type LimitType { get; } }
RegistrationBuilder.RegistrationDatano longer exposes the configuredActivatedHandlers,ActivatingHandlersorPreparingHandlers, andIComponentRegistrationno longer exposesPreparing,ActivatingorActivatedevents.All Autofac events are now implemented as
CoreEventMiddlewareadded to the resolve pipeline.// 5.x builder.RegisterCallback(x => { x.Registered += (sender, args) => { args.ComponentRegistration.Activated += (o, c) => { // Do something with the component instance var instance = c.Instance; }; }; }); // 6.x builder.ComponentRegistryBuilder.Registered += (sender, args) => { args.ComponentRegistration.PipelineBuilding += (sender2, pipeline) => { pipeline.Use(PipelinePhase.Activation, MiddlewareInsertionMode.EndOfPhase, (c, next) => { next(c); // Do something with the component instance var instance = c.Instance; }); }; };
If you need to inspect the set of event handlers added to the registration, you can inspect the registered middleware for instances of
CoreEventMiddleware:// Check if the registration has an OnActivated handler. if (registration.ResolvePipeline.Middleware.Any(c => c is CoreEventMiddleware ev && ev.EventType == ResolveEventType.OnActivated)) { }
It is no longer possible to access the set of Decorators for a registration using
IComponentRegistry.DecoratorsFor. Instead, if you need to access the set of decorators, (which you normally wouldn’t need to) use theIComponentRegistry.ServiceMiddlewareFormethod to get the middleware for a Service, and check for middleware that runs in theDecorationpipeline phase.Registrations that target a different registration, using the
Targetingregistration method, no longer need to specify anisAdapterForIndividualComponentparameter.The
ContainerBuilderis now marked assealed, so it cannot be overridden. It was never expected that you would overrideContainerBuilder, but some users saw undesirable behavior when they did.The constructor for
ResolveRequestnow takes aServiceRegistration, instead of anIComponentRegistration.