Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Register service with Interceptor, then register multiple decorator, auto apply Interceptor to the outermost decorator #1439

Merged
merged 2 commits into from
Dec 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 51 additions & 0 deletions src/Autofac/ServiceMiddlewareRegistrationExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,57 @@ public static void RegisterServiceMiddleware<TService>(this ContainerBuilder bui
builder.RegisterServiceMiddleware(typeof(TService), new DelegateMiddleware(descriptor, phase, callback), insertionMode);
}

/// <summary>
/// Register a resolve middleware for services providing a particular type.
/// </summary>
/// <param name="builder">The container builder.</param>
/// <param name="serviceType">The service type.</param>
/// <param name="phase">The phase of the pipeline the middleware should run at.</param>
/// <param name="callback">
/// A callback invoked to run your middleware.
/// This callback takes a <see cref="ResolveRequestContext"/>, containing the context for the resolve request, plus
/// a callback to invoke to continue the pipeline.
/// </param>
public static void RegisterServiceMiddleware(this ContainerBuilder builder, Type serviceType, PipelinePhase phase, Action<ResolveRequestContext, Action<ResolveRequestContext>> callback)
{
builder.RegisterServiceMiddleware(serviceType, AnonymousDescriptor, phase, MiddlewareInsertionMode.EndOfPhase, callback);
}

/// <summary>
/// Register a resolve middleware for services providing a particular type.
/// </summary>
/// <param name="builder">The container builder.</param>
/// <param name="serviceType">The service type.</param>
/// <param name="descriptor">A description for the middleware; this will show up in any resolve tracing.</param>
/// <param name="phase">The phase of the pipeline the middleware should run at.</param>
/// <param name="callback">
/// A callback invoked to run your middleware.
/// This callback takes a <see cref="ResolveRequestContext"/>, containing the context for the resolve request, plus
/// a callback to invoke to continue the pipeline.
/// </param>
public static void RegisterServiceMiddleware(this ContainerBuilder builder, Type serviceType, string descriptor, PipelinePhase phase, Action<ResolveRequestContext, Action<ResolveRequestContext>> callback)
{
builder.RegisterServiceMiddleware(serviceType, descriptor, phase, MiddlewareInsertionMode.EndOfPhase, callback);
}

/// <summary>
/// Register a resolve middleware for services providing a particular type.
/// </summary>
/// <param name="builder">The container builder.</param>
/// <param name="serviceType">The service type.</param>
/// <param name="descriptor">A description for the middleware; this will show up in any resolve tracing.</param>
/// <param name="phase">The phase of the pipeline the middleware should run at.</param>
/// <param name="callback">
/// A callback invoked to run your middleware.
/// This callback takes a <see cref="ResolveRequestContext"/>, containing the context for the resolve request, plus
/// a callback to invoke to continue the pipeline.
/// </param>
/// <param name="insertionMode">The insertion mode of the middleware (start or end of phase).</param>
public static void RegisterServiceMiddleware(this ContainerBuilder builder, Type serviceType, string descriptor, PipelinePhase phase, MiddlewareInsertionMode insertionMode, Action<ResolveRequestContext, Action<ResolveRequestContext>> callback)
{
builder.RegisterServiceMiddleware(serviceType, new DelegateMiddleware(descriptor, phase, callback), insertionMode);
}

/// <summary>
/// Register a resolve middleware for services providing a particular type.
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,46 @@ public void IfNotRegistered_CanHaveServiceMiddleware()
Assert.True(middlewareInvoked);
}

[Fact]
public void IfNotRegistered_EvaluatesServiceMiddleware()
{
var builder = new ContainerBuilder();
var middlewareInvoked = false;

builder.RegisterType<ServiceA>().As<IService>().IfNotRegistered(typeof(IService));

builder.RegisterServiceMiddleware(typeof(IService), PipelinePhase.ResolveRequestStart, (context, next) =>
{
next(context);
middlewareInvoked = true;
});

var container = builder.Build();
var result = container.Resolve<IService>();
Assert.True(middlewareInvoked);
}

[Fact]
public void IfNotRegistered_EvaluatesServiceMiddleware_WithDescriptor()
{
var builder = new ContainerBuilder();
var middlewareInvoked = false;

builder.RegisterType<ServiceA>().As<IService>().IfNotRegistered(typeof(IService));

const string descriptor = "custom-middleware";
builder.RegisterServiceMiddleware(typeof(IService), descriptor, PipelinePhase.ResolveRequestStart, (context, next) =>
{
next(context);
middlewareInvoked = true;
});

var container = builder.Build();

var result = container.Resolve<IService>();
Assert.True(middlewareInvoked);
}

[Fact]
public void IfNotRegistered_CanBeDecoratedByModuleWhenModuleRegistered1st()
{
Expand Down