问题
Packages: Autofac.Extensions.DependencyInjection (6.0.0), Autofac.extras.DynamicProxy(4.5.0)
I am trying to prototype an interceptor for all of our service classes/interface serving the Web API controllers in our application, by following the ASP.NET Core 4.0 and the Interceptor documentation. The Interceptor is just a simple Log action using Serlog:
public MethodCallInterceptor()
{
}
public void Intercept(IInvocation invocation)
{
var text = invocation.Method.Name;
Log.Logger.Debug($"Interceptor (Method): {text}");
invocation.Proceed();
}
Our main application sets up Autofac with ComApiApplication as the "Startup" class:
public static void Main(string[] args)
{
CreateHostBuilder(args).Build().Run();
}
public static IHostBuilder CreateHostBuilder(string[] args)
{
return Host.CreateDefaultBuilder(args)
.UseServiceProviderFactory(new AutofacServiceProviderFactory())
.ConfigureWebHostDefaults(webBuilder => webBuilder.UseStartup<ComsApiApplication>());
}
In ComsApiApplication, I register most of ASP.NET MVC services in ConfigureServices (e.g. Authentication, Authorization etc). Then, I hook up the Interceptor for classes in a couple of our service assembles in its ConfigureContainer function:
public void ConfigureContainer(ContainerBuilder builder)
{
foreach (var assembly in Options.Assemblies)
{
// Add application services: IService => Service.
var registrations = assembly.GetExportedTypes()
.Where(type => type.Namespace != null && type.Namespace.Contains(".Services") && type.GetInterfaces().Any() && !type.IsAbstract)
.Select(type => new
{
Service = type.GetInterfaces().Single(inf => inf.Name.Contains(type.Name)),
Implementation = type
});
foreach (var registration in registrations)
{
//builder.RegisterType(registration.Implementation).As(registration.Service).InstancePerDependency().EnableInterfaceInterceptors().InterceptedBy(typeof(MethodCallInterceptor));
builder.RegisterType(registration.Implementation).As(registration.Service).EnableInterfaceInterceptors().InstancePerDependency().InterceptedBy(typeof(MethodCallInterceptor));
}
builder.Register(c => new MethodCallInterceptor());
}
}
However, when I run the application with requests leading to call the interface functions in those services (inheritance exists in our interfaces and service classes), I get the following exception and would be grateful for any help in identifying my issue:
Autofac.Core.DependencyResolutionException: An exception was thrown while executing a resolve operation. See the InnerException for details.
---> Castle.DynamicProxy.ProxyGenerationException: This is a DynamicProxy2 error: Target type for the proxy implements Castle.DynamicProxy.IProxyTargetAccessor which is a DynamicProxy infrastructure interface and you should never implement it yourself. Are you trying to proxy an existing proxy?
at Castle.DynamicProxy.Generators.BaseProxyGenerator.HandleExplicitlyPassedProxyTargetAccessor(ICollection1 targetInterfaces, ICollection
1 additionalInterfaces)
at Castle.DynamicProxy.Generators.InterfaceProxyWithTargetGenerator.GetTypeImplementerMapping(Type[] interfaces, Type proxyTargetType, IEnumerable1& contributors, INamingScope namingScope)
at Castle.DynamicProxy.Generators.InterfaceProxyWithTargetGenerator.GenerateType(String typeName, Type proxyTargetType, Type[] interfaces, INamingScope namingScope)
at Castle.DynamicProxy.Generators.InterfaceProxyWithTargetGenerator.<>c__DisplayClass6_0.<GenerateCode>b__0(String n, INamingScope s)
at Castle.DynamicProxy.Generators.BaseProxyGenerator.ObtainProxyType(CacheKey cacheKey, Func
3 factory)
at Castle.DynamicProxy.Generators.InterfaceProxyWithTargetGenerator.GenerateCode(Type proxyTargetType, Type[] interfaces, ProxyGenerationOptions options)
at Castle.DynamicProxy.DefaultProxyBuilder.CreateInterfaceProxyTypeWithTarget(Type interfaceToProxy, Type[] additionalInterfacesToProxy, Type targetType, ProxyGenerationOptions options)
at Castle.DynamicProxy.ProxyGenerator.CreateInterfaceProxyTypeWithTarget(Type interfaceToProxy, Type[] additionalInterfacesToProxy, Type targetType, ProxyGenerationOptions options)
at Castle.DynamicProxy.ProxyGenerator.CreateInterfaceProxyWithTarget(Type interfaceToProxy, Type[] additionalInterfacesToProxy, Object target, ProxyGenerationOptions options, IInterceptor[] interceptors)
at Castle.DynamicProxy.ProxyGenerator.CreateInterfaceProxyWithTarget(Type interfaceToProxy, Type[] additionalInterfacesToProxy, Object target, IInterceptor[] interceptors)
at Autofac.Extras.DynamicProxy.RegistrationExtensions.<>c__DisplayClass9_03.<EnableInterfaceInterceptors>b__0(Object sender, ActivatingEventArgs
1 e)
at Autofac.Core.Registration.ComponentRegistration.RaiseActivating(IComponentContext context, IEnumerable1 parameters, Object& instance)
at Autofac.Core.Resolving.InstanceLookup.Activate(IEnumerable
1 parameters, Object& decoratorTarget)
at Autofac.Core.Resolving.InstanceLookup.Execute()
at Autofac.Core.Resolving.ResolveOperation.GetOrCreateInstance(ISharingLifetimeScope currentOperationScope, ResolveRequest request)
at Autofac.Core.Resolving.ResolveOperation.ResolveComponent(ResolveRequest request)
at Autofac.Core.Resolving.ResolveOperation.Execute(ResolveRequest request)
--- End of inner exception stack trace ---
at Autofac.Core.Resolving.ResolveOperation.Execute(ResolveRequest request)
at Autofac.Core.Lifetime.LifetimeScope.ResolveComponent(ResolveRequest request)
at Autofac.ResolutionExtensions.TryResolveService(IComponentContext context, Service service, IEnumerable1 parameters, Object& instance)
at Autofac.ResolutionExtensions.ResolveOptionalService(IComponentContext context, Service service, IEnumerable
1 parameters)
at Autofac.ResolutionExtensions.ResolveOptional(IComponentContext context, Type serviceType, IEnumerable`1 parameters)
at Autofac.ResolutionExtensions.ResolveOptional(IComponentContext context, Type serviceType)
at Autofac.Extensions.DependencyInjection.AutofacServiceProvider.GetService(Type serviceType)
at Microsoft.Extensions.DependencyInjection.ActivatorUtilities.GetService(IServiceProvider sp, Type type, Type requiredBy, Boolean isDefaultParameterRequired)
at lambda_method(Closure , IServiceProvider , Object[] )
at Microsoft.AspNetCore.Mvc.Controllers.ControllerActivatorProvider.<>c__DisplayClass4_0.b__0(ControllerContext controllerContext)
at Microsoft.AspNetCore.Mvc.Controllers.ControllerFactoryProvider.<>c__DisplayClass5_0.g__CreateController|0(ControllerContext controllerContext)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.InvokeInnerFilterAsync()
--- End of stack trace from previous location where exception was thrown ---
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.g__Awaited|25_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
Microsoft.AspNetCore.Mvc.Infrastructure.SystemTextJsonResultExecutor: Information: Executing JsonResult, writing value of type 'System.String'.
回答1:
The following is from Google Translate: Coincidentally, I just solved this problem, but this is not the correct solution. Just need to downgrade the Autofac.Extensions.DependencyInjection package to 5.0.1 to solve the problem.
来源:https://stackoverflow.com/questions/60067943/unable-to-hook-up-interceptor-on-classes-interfaces-in-asp-net-core-3-1-applicat