1

I would like to extend my service registration [e.g. EnableInterfaceInterceptors] from Autofac Pipeline. However, I couldn't find a way to achieve that. Is there any entrypoint for me to access the registration as IRegistrationBuilder?

Provided codes below for your reference

containerBuilder.RegisterGeneric(typeof(CredentialService<>)).InstancePerDependency()
.ConfigurePipeline(p =>
{
    p.Use(PipelinePhase.RegistrationPipelineStart, (context, next) =>
    {
        // WHAT SHOULD I DO HERE TO GET BACK THE IRegistrationBuilder IN ORDER TO EXTEND MY REGISTRATION?

        next(context);
    });
});

Thanks in advance

mannok
  • 1,712
  • 1
  • 20
  • 30

1 Answers1

2

Autofac docs

The context object passed into all middleware is an instance of ResolveRequestContext. This object stores the initial attributes of a resolve request, and any properties updated while the request executes.

You can use this context to:

  • Check the service being resolved with the Service property.
  • Check the Registration being used to provide the service.
  • Get or set the result of the resolve operation with the Instance property.
  • Access the parameters of the request with the Parameters property and change those parameters with the ChangeParameters method.
  • Resolve another service (using any of the normal Resolve methods).

In short

Although it is called registration pipeline, it is actually used when a resolve request occurs.

Instances of IRegistrationBuilder are not stored anywhere except in the configuration callback (see details below), hence you cannot access them in the pipeline in any way.

By the time your pipeline delegate is being executed, IRegistrationBuilder instances are already gone. You have only the IComponentRegistration instance in the ResolveRequestContext.Registration property.

In detail

  • When an instance of IRegistrationBuilder is created then
    • It will have an instance of RegistrationData that contains the Lifetime, Metadata, Options, Ownership and Sharing properties. The extension methods of IRegistrationBuilder actually configures these properties.
    • It will also have an instance of IResolvePipelineBuilder field you actually configure with the .ConfigurePipeline() extension method.
    • It will register a configuration callback into the current ContainerBuilder instance with the IRegistrationBuilder instance.
  • These callbacks are executed by the ContainerBuilder.Build() method.
  • When the callback is executed then it will create an instance of IComponentRegistration from the IRegistrationBuilder instance.
  • This IComponentRegistration contains the same properties that come from the RegistrationData and also gets the configured IResolvePipelineBuilder.
var registrationBuilder =
    containerBuilder
        .RegisterType<ServiceWithDependency>()
        .AsSelf()
        .InstancePerDependency();

registrationBuilder.ConfigurePipeline(
    resolvePipelineBuilder =>
    {
        resolvePipelineBuilder.Use(
            PipelinePhase.RegistrationPipelineStart,
            (context, next) =>
            {
                // context is ResolveRequestContext
                // context.Registration is IComponentRegistration

                next(context);

                // Autofac.Extras.DynamicProxy
                // EnableInterfaceInterceptors() extension method actually uses
                // - context.Registration
                // - context.Instance (this will be overridden with the generated proxy)
                // - context.ResolveService(...)

                // You may also use these properties from context.Registration
                // - context.Registration.Lifetime
                // - context.Registration.Metadata
                // - context.Registration.Options
                // - context.Registration.Ownership
                // - context.Registration.Sharing
            }
        );
    }
);
Gabor
  • 3,021
  • 1
  • 11
  • 20
  • thanks @Gabor, very detail explanation. So, does it mean that I could learn deal with `EnableInterfaceInterceptors()` from `ConfigurePipeline()` by registrating a component with `EnableInterfaceInterceptors()` once in normal way and then see what have been added into `context.Registration`, `context.Instance` and `context.ResolveService`? – mannok Jan 21 '23 at 01:31
  • update: I have searched through the `context.Registration` before `next(context)` but did not find any related information related to DynamicProxy/Interceptor even I tried to register the service with `EnableInterfaceInterceptors()`. I expect there should be some flag/identifier from `context.Registration` to specify this service will be intercepted – mannok Jan 21 '23 at 03:11
  • @mannok, when you call `EnableInterfaceInterceptors()` method on your registration, it will configure only a callback delegate for the pipeline but that delegate will only be executed when you or the app tries to resolve something. This delegate uses those properties I mentioned. So you can't check what have been added right after your method call because at that time it has not been executed yet. You can check what that method exactly does [here](https://github.com/autofac/Autofac.Extras.DynamicProxy/blob/develop/src/Autofac.Extras.DynamicProxy/RegistrationExtensions.cs#L155). – Gabor Jan 21 '23 at 23:44