Base solution for your next web application
Open Closed

Best way of handling isolated (external incoming) events? #2358


User avatar
0
juanmanuelrios created

Which is the best way to handle incoming events from external sources, like message queuing, since we don't have a current context available, I mean I want to process those messages inside a correct ABP context in terms of unit of work, localization manager, inject repositories, managers, etc.

I was looking around BackgroundManager implementation to have a hint on this way, but I'm not sure if I'm on the right way.

Many thanks in advance, and thanks for your great work!


4 Answer(s)
  • User Avatar
    0
    ismcagdas created
    Support Team

    Hi,

    Currently the best way is to accept those request via webapi methods. In your web api methods, you can save those requests for background job processing or you can process them directly.

  • User Avatar
    0
    juanmanuelrios created

    Thanks for your response.

    I'm not able to handle that way because using of message queue is mandatory in our case. This strenght comes from an architectural definition for server-to-server integration. While server is running it pushes messages to queue for notifications that must be processed on another one (last one on top of aspnetboilerplate)

    Maybe a good starting point is to create a queue consumer registered as singleton, injecting IoCResolver on it. At at time a message is received, I must be able to set up a DbContext, UnitOfWork, set current tentant, etc., and then invoke app service class to do their job.

    Please, let me know if I am o the correct way.

    Many thanks.

  • User Avatar
    0
    hikalkan created
    Support Team

    Hi,

    It's actually simple. Think that you have created a class like that:

    public class MessageProcessor : ITransientDependency
    {
        [UnitOfWork]
        public virtual void Process(Message m)
        {
            ...
        }
    }
    

    Now, your MessageProcessor is registered to dependency injection (it can inject any service) and the Process method is unit of work.

    Now, in some point of your message handler, you can use IocManager.Instance to create an instance of MessageProcessor and process the message:

    using(var processor = IocManager.Instance.ResolveAsDisposable<MessageProcessor>())
    {
        processor.Object.Process(...);
    }
    

    You can wrap this code into a try-catch to understand if there is an exception. If no exception, you can delete message from the message queue system.

    The key point is here: IocManager.Instance provides access to the DI container and makes you enter to DI context (and therefore ABP context). You can inject and use any service.

    But, as a best practice, I suggest to avoid using application services from your background job / message queue code. Because, app services may have additional rules (like validation and authorization) you probably don't want to execute for background jobs. In that case, I suggest you to extract logic into a domain service which can be re-usable by the app service and the background job.

  • User Avatar
    0
    juanmanuelrios created

    Excellent!

    Many thanks for the advice, I realized that is pretty easy to do. I'll give it a shot...

    By the way, you have done great work on ABP!

    Best regards.