I am trying to start using middleware and creating a logger for a project and thought the autofac log4net example was a good starting point as the project already is making use of autofac, but I am not being able to do so. I have the following classes:
using System; using System.Linq; using System.Reflection; using Autofac; using Autofac.Core; using Autofac.Core.Registration; using Autofac.Core.Resolving.Pipeline; using log4net; using Microsoft.VisualStudio.TestTools.UnitTesting; namespace TestProject1 { public class TestMiddlewareModule : Autofac.Module { private readonly IResolveMiddleware middleware; public TestMiddlewareModule(IResolveMiddleware middleware) { this.middleware = middleware; } protected override void AttachToComponentRegistration(IComponentRegistryBuilder componentRegistryBuilder, IComponentRegistration registration) { // Attach to the registration's pipeline build. registration.PipelineBuilding += (sender, pipeline) => { // Add our middleware to the pipeline. pipeline.Use(middleware); }; } } public class TestLog4NetMiddleware : IResolveMiddleware { public PipelinePhase Phase => PipelinePhase.ParameterSelection; public void Execute(ResolveRequestContext context, Action<ResolveRequestContext> next) { // Add our parameters. context.ChangeParameters(context.Parameters.Union( new[] { new ResolvedParameter( (p, i) => p.ParameterType == typeof(ILog), (p, i) => LogManager.GetLogger(p.Member.DeclaringType) ), })); // Continue the resolve. next(context); // Has an instance been activated? if (context.NewInstanceActivated) { var instanceType = context.Instance.GetType(); // Get all the injectable properties to set. // If you wanted to ensure the properties were only UNSET properties, // here's where you'd do it. var properties = instanceType .GetProperties(BindingFlags.Public | BindingFlags.Instance) .Where(p => p.PropertyType == typeof(ILog) && p.CanWrite && p.GetIndexParameters().Length == 0); // Set the properties located. foreach (var propToSet in properties) { propToSet.SetValue(context.Instance, LogManager.GetLogger(instanceType), null); } } } } [TestClass] public class UnitTestLog4Net { public ILog logger { get; set; } public TestContext TestContext { get; set; } // Create your builder. private static ContainerBuilder container = new ContainerBuilder(); private static IContainer builder; protected ILifetimeScope scope; [TestMethod] public void TestMethodLog4Net() { container.RegisterType<TestLog4NetMiddleware>() .As<IResolveMiddleware>() .AsSelf() ; container.RegisterServiceMiddleware<Log4NetMiddleware>(new Log4NetMiddleware()) //.AsImplementedInterfaces() ; container.RegisterAssemblyModules(Assembly.GetExecutingAssembly()); builder = container.Build(); scope = builder.BeginLifetimeScope(); logger.Info("TEST"); } } } However the test always fails with:
TestProject1.UnitTestLog4Net.TestMethodLog4Net threw exception: Autofac.Core.DependencyResolutionException: An exception was thrown while activating λ:Autofac.Core.IModule[] -> TestProject1.TestMiddlewareModule. ---> Autofac.Core.DependencyResolutionException: None of the constructors found with 'Autofac.Core.Activators.Reflection.DefaultConstructorFinder' on type 'TestProject1.TestMiddlewareModule' can be invoked with the available services and parameters: Cannot resolve parameter 'Autofac.Core.Resolving.Pipeline.IResolveMiddleware middleware' of constructor 'Void .ctor(Autofac.Core.Resolving.Pipeline.IResolveMiddleware)'.
But the line container.RegisterType<TestLog4NetMiddleware>().As<IResolveMiddleware>().AsSelf(); should have registered TestLog4NetMiddleware as a valid IResolveMiddleware
What am I doing wrong?