question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Autofac and Pipeline Behavior

See original GitHub issue

I am trying to get new pipeline working with autofac but it is running the same pipeline many times with different types.

Adding the following class the MediatR example

public class BehaviorOne<TRequest, TResponse> : IPipelineBehavior<TRequest, TResponse> 
    {

        private readonly TextWriter _writer;

        public BehaviorOne(TextWriter writer)
        {
            _writer = writer;
        }

        public async Task<TResponse> Handle(TRequest request, RequestHandlerDelegate<TResponse> next)
        {
            //System.Diagnostics.Trace.WriteLine($"BehaviorOne - Handle {typeof(TRequest).Name}");

            _writer.WriteLine("BehaviorOne - Handle " + typeof(TRequest).Name);

            var response = await next();

            return response;
        }
    }

Added this to the BuildMediator for the autofac example program.cs

builder.RegisterGeneric(typeof(BehaviorOne<,>)).As(typeof(IPipelineBehavior<,>));

Produced the following output:

Sample mediator implementation using send, publish and post-request handlers in sync and async version.
---------------
Sending Ping...
BehaviorOne - Handle Ping
BehaviorOne - Handle Object
BehaviorOne - Handle IRequest`1
Received: Ping Pong
Sending Ping async...
BehaviorOne - Handle PingAsync
BehaviorOne - Handle Object
BehaviorOne - Handle IRequest`1
Received async: Ping Pong
Publishing Pinged...
Got pinged also.
Got pinged.
Got notified.
Got notified also async.
Publishing Pinged async...
Got notified.
Got pinged also async.
Got pinged async.
Got notified also async.

For the structure map example you get:

Sample mediator implementation using send, publish and post-request handlers in sync and async version.
---------------
Sending Ping...
BehaviorOne - Handle Ping
Received: Ping Pong
Sending Ping async...
BehaviorOne - Handle PingAsync
Received async: Ping Pong
Publishing Pinged...
Got notified.
Got pinged.
Got pinged also.
Got notified also async.
Publishing Pinged async...
Got notified.
Got notified also async.
Got pinged async.
Got pinged also async.

Issue Analytics

  • State:closed
  • Created 7 years ago
  • Comments:20 (3 by maintainers)

github_iconTop GitHub Comments

8reactions
serochecommented, Sep 5, 2019

Hey guys,

I had the same problem this morning and I solved by implementing my own ScopedContravariantRegistrationSource (as advised by jdaigle). It’s a simplistic (probably incomplete) implementation but it works quite well with my easy use case:

Here is the code:

    public class ScopedContravariantRegistrationSource : IRegistrationSource
    {
        private readonly IRegistrationSource _source = new ContravariantRegistrationSource();
        private readonly List<Type> _types = new List<Type>();

        public ScopedContravariantRegistrationSource(params Type[] types)
        {
            if (types == null)
                throw new ArgumentNullException(nameof(types));
            if (!types.All(x => x.IsGenericTypeDefinition))
                throw new ArgumentException("Supplied types should be generic type definitions");
            _types.AddRange(types);
        }

        public IEnumerable<IComponentRegistration> RegistrationsFor(
            Service service,
            Func<Service, IEnumerable<IComponentRegistration>> registrationAccessor)
        {
            var components = _source.RegistrationsFor(service, registrationAccessor);
            foreach (var c in components)
            {
                var defs = c.Target.Services
                    .OfType<TypedService>()
                    .Select(x => x.ServiceType.GetGenericTypeDefinition());

                if (defs.Any(_types.Contains))
                    yield return c;
            }
        }

        public bool IsAdapterForIndividualComponents => _source.IsAdapterForIndividualComponents;
    }

Then simply call in Startup: then builder.RegisterSource(typeof(MyBehavior<,>));

Regards, Seb

2reactions
jdaiglecommented, Mar 15, 2017

Part of the problem with the ContravariantRegistrationSource is that it applies to any service resolved. Instead, we want it limited in scope.

For a project I ended up implementing my own ScopedContravariantRegistrationSource (largely copy/pasted the original source but added code to restrict which services it applied to via constructor parameter). Then register this source for only the services you want to have contravariant resolution.

It’s certainly not as flexible as StructureMap’s configuration, but it works decently well.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Resolve Pipelines — Autofac 7.0.0 documentation
In Autofac (from version 6.0 onwards), the work of actually resolving an instance of a registration when a service is requested is implemented...
Read more >
Register IPipelineBehavior in ASP.NET Core 3 with autofac
I want to register pipeline behavior in my project and register that by autofac. I implement that by this way :
Read more >
Advanced Topics — Autofac 7.0.0 documentation
Reference Packages for WCF Integration · Passing Tenant ID with a Behavior · Tenant Identification from OperationContext · Hosting Multitenant Services.
Read more >
CQRS with MediatR and Autofac in .NET 6 - Tech Playground
In this particular article, we use MediatR.Extensions.Autofac.DependencyInjection , which helps connecting MediatR to Autofac. Autofac fits well ...
Read more >
Autofac + MediatR - Shared transaction between ORMs on ...
First, you need to create new pipeline behavior - an action which embraces every command. It is a mechanism very well defined in...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found