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
IConstructorSelector
to pass to theUsingConstructor
registration method, you will need to update your implementation to useBoundConstructor
instead ofConstructorParameterBinding
. The newBoundConstructor
type 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.RegistrationsFor
method.// 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
registrationAccessor
parameter 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
ServiceRegistration
encapsulates the registration (via theRegistration
property 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 anActivateInstance
method 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.RegistrationData
no longer exposes the configuredActivatedHandlers
,ActivatingHandlers
orPreparingHandlers
, andIComponentRegistration
no longer exposesPreparing
,Activating
orActivated
events.All Autofac events are now implemented as
CoreEventMiddleware
added 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.ServiceMiddlewareFor
method to get the middleware for a Service, and check for middleware that runs in theDecoration
pipeline phase.Registrations that target a different registration, using the
Targeting
registration method, no longer need to specify anisAdapterForIndividualComponent
parameter.The
ContainerBuilder
is 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
ResolveRequest
now takes aServiceRegistration
, instead of anIComponentRegistration
.