Code Monkey home page Code Monkey logo

rebus.autofac's People

Contributors

kendallb avatar leomenca avatar mookid8000 avatar oliverhanappi avatar trreeves avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

rebus.autofac's Issues

New Rebus Autofac - could not be dispatched to any handlers

A little late to the game but updated my nuget packages and got a new Rebus Autofac.
Is there a new way to register the handlers ?

This was how I did it before:
//_builder.RegisterAssemblyTypes(typeof(HeartBeatCommandHandler).Assembly)
// .Where(x => typeof(IHandleMessages).IsAssignableFrom(x))
// .AsClosedTypesOf(typeof(IHandleMessages<>))
// .AsImplementedInterfaces()
// .InstancePerDependency()
// .PropertiesAutowired();

But now I'm getting ...could not be dispatched to any handlers.

Using RegisterHandlersFromAssemblyOf, it subscribes to all messages

Hi, thanks for implementing Rebus and all it's goodies!

I am using RegisterHandlersFromAssemblyOf to register my handlers.
However, based on my understanding, even though I use it, I still need to subscribe to particular messages.

The scenario I have
I want to register all handlers( let's say I have 3 handlers ) in an assembly and based on a config value, I want to subscribe only to some messages (not all). So, I call RegisterHandlersFromAssemblyOf, I build the container, I subscribe to only 1 message type but when I run the application, my app handles all 3 types of messages.

If I use builder.RegisterHandler and register only the handler I need, it then handles only that type of message after I subscribe to it.

Is it a bug or I missunderstood how to use RegisterHandlersFromAssemblyOf + Subscribe?

Thank you!

Rebus.Autofac can't resolve generics IFailed<T>, making SecondLevelTry to fail

When GetHandlerInvokers in ActivateHandlersStep for a failed message (FailedMessageWrapper), no invokers can be found, resulting in an empy list of handlers.

Register in Rebus.Autofac:

autofacBus.Subscribe<string>().Wait();
autofacBus.Subscribe<IFailed<string>>().Wait();

--> Do not work!

Register with BuildInActivator:

rebusActivator.Bus.Subscribe<string>();
rebusActivator.Bus.Subscribe<IFailed<string>>();

-- Working OK!

Resolve ComponentContext from steps

Hi! I noticed that ComponentContext cannot be resolved in steps like in Rebus.ServiceProvider package where the ServiceProviderProviderStep provides the ServiceProvider for the rest of the pipeline. Would it be possible to enable resolving ComponentContext in steps for the next version?

For example in my project we are using rebus middleware to fetch the headers from http context and set them to message context for audit purposes. Something like this:

`/// <summary>
    /// Implementation of <see cref="IOutgoingStep"/> that fetches the requestId neccesseary for audit trail
    /// from Http Context and attaches it to rebus message context.
    /// </summary>
    internal class AttachRequestIdToOutgoingMessagesStep : IOutgoingStep
    {
        public async Task Process(OutgoingStepContext context, Func<Task> next)
        {
            var componentContext = context.Load<IComponentContext>();
            var httpContextAccessor = componentContext.Resolve<IHttpContextAccessor>();

            var requestId = httpContextAccessor.HttpContext.Request.Headers["x-request-id"];

            if (!string.IsNullOrWhiteSpace(requestId))
            {
                var message = context.Load<Message>();
                message.Headers["x-request-id"] = requestId.ToString();
            }

            await next();
        }
    }`

But in order for our steps to be able to resolve services from ComponentContext, I created an extension method which will enable the ComponentContextProviderStep to provide the ComponentContext for the rest of the pipeline. Like this:

`[StepDocumentation("Adds the component context to the incoming/outgoing step context, thus making it available for the rest of the pipeline.")]
    public class ComponentContextProviderStep : IIncomingStep, IOutgoingStep
    {
        readonly IComponentContext _context;

        /// <summary>
        /// Creates the step
        /// </summary>
        public ComponentContextProviderStep(IComponentContext context) =>
            _context = context ?? throw new ArgumentNullException(nameof(context));

        /// <summary>
        /// Saves the component context in the pipeline's context and invokes the rest of the pipeline
        /// </summary>
        public async Task Process(IncomingStepContext context, Func<Task> next)
        {
            context.Save(_context);
            await next();
        }

        /// <summary>
        /// Saves the component context in the pipeline's context and invokes the rest of the pipeline
        /// </summary>
        public async Task Process(OutgoingStepContext context, Func<Task> next)
        {
            context.Save(_context);
            await next();
        }
    }`

Also I played around a bit with the Rebus.Autofac package and managed to set up the ComponentContextProviderStep.
Like this:

`public static void RegisterRebus(this ContainerBuilder containerBuilder, Func<RebusConfigurer, IComponentContext, RebusConfigurer> configure)
        {
            if (containerBuilder == null) throw new ArgumentNullException(nameof(containerBuilder));
            if (configure == null) throw new ArgumentNullException(nameof(configure));
 
            new AutofacHandlerActivator(containerBuilder, (configurer, context) => configure(
                configurer.Options(o => o.Decorate<IPipeline>(c =>
                {
                    var pipeline = c.Get<IPipeline>();
                    var step = new ComponentContextProviderStep(context.Resolve<IComponentContext>());

                    return new PipelineStepConcatenator(pipeline)
                                .OnReceive(step, PipelineAbsolutePosition.Front)
                                .OnSend(step, PipelineAbsolutePosition.Front);
                }))
                , context), startBus: true, enablePolymorphicDispatch: false);
        }`

I tested this and it works fine (I was able to resolve HttpContextAccessor in my test step) but I'm not sure if this is the right implementation.

How to resolve in new Configurer API?

With the old API, we could access IComponentContext to resolve components used in the Rebus configuration - e.g. IDocumentStore if using the RavenDB connectors.

e.g.

var busConfiguration = Rebus.Config.Configure.With(new AutofacContainerAdapter(c.Resolve<IContainer>()))
.Logging(l => l.Serilog(Log.Logger))
.Timeouts(t => t.StoreInRavenDb(c.Resolve<IDocumentStore>()))
.Sagas(s => s.StoreInRavenDb(c.Resolve<IDocumentStore>()))
.Transport(t => t.UseRabbitMq(connectionString, inputQueueName))

How can we access the ComponentContext with this new API to allow for resolving components for the transport registrations etc?

Cheers.

Change casing in package references.

Hi,

Could you change line 50 in https://github.com/rebus-org/Rebus.Autofac/blob/master/Rebus.Autofac/Rebus.Autofac.csproj to use the correct casing.
If you are using .NET Core with project.json files this causes an issue that rebus cannot be found (since it should be Rebus)

Before:

<ItemGroup>

    <PackageReference Include="rebus" Version="4.0.0-b05" />

    <PackageReference Include="Autofac" Version="4.4.0" />

</ItemGroup>

After:

 <ItemGroup>

    <PackageReference Include="Rebus" Version="4.0.0-b05" />

    <PackageReference Include="Autofac" Version="4.4.0" />

</ItemGroup>

Thanks

Previous API allowed exposing RebusConfigurer

Thanks for the changes allowing access to IComponentContext.

I must say though, I do prefer the existing approach. This allowed for exposing RebusConfigurer separately before the bus was created.

This allowed for the container to create the RebusConfigurer instance with all the default options and properties etc, but allowed for the Routing to be configured before creating the bus.

Since there's no option (as far as i know?) to mess with routing after the bus is created, this results in a lot of boilerplate code to configure the bus instead of creating it with the majority of options by IoC.

Am I missing some sort of option to configure routing after the bus is created?

How to postpone bus start up?

Hello guys,
One of the common scenario for ASP .NET Core application is registering all dependencies in ConfigureServices method and applying DB migrations in Configure method in Startup class.
In case of using SQL based transport for messages, database may not exist on the moment of container build up. Why Rebus.Autofac decides when to start up the bus?

NullReference exception if message received before initialization finished

I use the lib with rabbitMq. Config is something like

   builder.RegisterRebus((configurer, context) => configurer
                    .Logging(l => l.Serilog())
                    .Transport(t => t.UseRabbitMq("amqp://docker", "testappqueue"))
                .Options(o => {
                    o.SetNumberOfWorkers(1);
                    o.SetMaxParallelism(30);
                }));

If a message was received by rabbitMq while the application was not running it tries to process the message before initialization finished. The reason is _container is null in the code below

ILifetimeScope CreateLifetimeScope()
            {
                var scope = _container.BeginLifetimeScope();
                transactionContext.OnDisposed(() => scope.Dispose());
                return scope;
            }

Duplicate handlers in case of ContravariantRegistrationSource

Hello!

There is a problem with the current implementation of AutofacHandlerActivator. In case an application uses ContravariantRegistrationSource the handlers will be duplicated due to this code:
var typesToResolve = messageType.GetBaseTypes()
.Concat(new[] {messageType})

ContravariantRegistrationSource already returns handlers for base types automatically, so you just add them one more time.

The possible solution is to add Distinct before returning the list of handlers:
return types.SelectMany(type => (IEnumerable<IHandleMessages>) lifetimeScope.Resolve(type)).Distinct();

Graceful shutdown?

I am not sure if there is an issue per-se, but I am investigating an issue we are seeing sometimes where a message handler is being executed after the root container has been disposed, throwing ObjectDisposedException's.

In my digging I fell upon this interesting issue over on the Rebus main repository: rebus-org/Rebus#976

It sounds very similar and from the looks of it, it was resolved by the RebusBackgroundService here: https://github.com/rebus-org/Rebus.ServiceProvider/blob/master/Rebus.ServiceProvider/ServiceProvider/Internals/RebusBackgroundService.cs

The thing is, we are using Autofac as out IoC layer, on top of ServiceProvider / IServiceCollection. And from the looks of it, I cannot find any similar code in this repository handling the graceful shutdown when the root container is disposed.

Might there be a similar edge case here?

It occurs rather seldom, but often enough to be a source of noise in our logs ๐Ÿ™ˆ

restriction to one bus per container

Is there a reason why only one bus is allowed per autofac container? On our project we would like to register 2 buses through keyed injection, each with a different transport. Is that possible?

Thanks

RebusConfigurer instance from Autofac

While using Autofac container, is it possible to get the rebusConfigurer instance as we get with BuiltInActivator?

Activator = new BuiltinHandlerActivator();
RebusConfigurer rebusConfigurer = Configure.With(Activator);

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.