Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Service Not Registered, Calling Module from other Module #13

Open
ozgunlu opened this issue Sep 12, 2023 · 5 comments
Open

Service Not Registered, Calling Module from other Module #13

ozgunlu opened this issue Sep 12, 2023 · 5 comments
Assignees
Labels
bug Something isn't working

Comments

@ozgunlu
Copy link

ozgunlu commented Sep 12, 2023

using BuildingBlocks.Abstractions.CQRS.Command;
using BuildingBlocks.Abstractions.Messaging;
using BuildingBlocks.Abstractions.Messaging.Context;
using BuildingBlocks.Abstractions.Persistence;
using BuildingBlocks.Core.Messaging;
using ECommerce.Modules.Customers.RestockSubscriptions.Features.ProcessingRestockNotification;

namespace ECommerce.Modules.Customers.Products.Features.ReplenishingProductStock.Events.External;

public record ProductStockReplenished(long ProductId, int NewStock, int ReplenishedQuantity) :
    IntegrationEvent,
    ITxRequest;

public class ProductStockReplenishedConsumer : IMessageHandler<ProductStockReplenished>
{
    private readonly ICommandProcessor _commandProcessor;
    private readonly ILogger<ProductStockReplenishedConsumer> _logger;

    public ProductStockReplenishedConsumer(
        ICommandProcessor commandProcessor,
        ILogger<ProductStockReplenishedConsumer> logger)
    {
        _commandProcessor = commandProcessor;
        _logger = logger;
    }

    // If this handler is called successfully, it will send a ACK to rabbitmq for removing message from the queue and if we have an exception it send an NACK to rabbitmq
    // and with NACK we can retry the message with re-queueing this message to the broker
    public async Task HandleAsync(
        IConsumeContext<ProductStockReplenished> messageContext,
        CancellationToken cancellationToken = default)
    {
        var productStockReplenished = messageContext.Message;

        await _commandProcessor.SendAsync(
            new ProcessRestockNotification(productStockReplenished.ProductId, productStockReplenished.NewStock),
            cancellationToken);

        _logger.LogInformation(
            "Sending restock notification command for product {ProductId}",
            productStockReplenished.ProductId);
    }
}

Above SendAsync method works sometimes, sometimes throw an error:

Error constructing handler for request of type MediatR.IRequestHandler`2[ECommerce.Modules.Customers.RestockSubscriptions.Features.ProcessingRestockNotification.ProcessRestockNotification,MediatR.Unit]. Register your handlers with the container. See the samples in GitHub for examples.

@ozgunlu ozgunlu closed this as completed Dec 5, 2023
@ozgunlu ozgunlu reopened this Dec 5, 2023
@DiperUa
Copy link

DiperUa commented Mar 16, 2024

same :(

@DiperUa
Copy link

DiperUa commented Mar 17, 2024

I tried getting IServiceProvider from CompositionRootRegistry.GetByModule, and it seems to work

@ozgunlu
Copy link
Author

ozgunlu commented Mar 17, 2024

I tried getting IServiceProvider from CompositionRootRegistry.GetByModule, and it seems to work

could you share code? I fixed that issue with SendScheduleAsync

@DiperUa
Copy link

DiperUa commented Mar 17, 2024

public class UserRegisteredConsumer : IMessageHandler<UserRegistered>
{
    private readonly IServiceProvider _serviceProvider;

    public UserRegisteredConsumer()
    {
        _serviceProvider =
            CompositionRootRegistry.GetByModule<CustomerModuleConfiguration>().ServiceProvider;
    }

    public async Task HandleAsync(
        IConsumeContext<UserRegistered> messageContext,
        CancellationToken cancellationToken = default
    )
    {
        var userRegistered = messageContext.Message;
        var scope = _serviceProvider.CreateScope();
        var commandProcessor = scope.ServiceProvider.GetRequiredService<ICommandProcessor>();
        await commandProcessor.SendAsync(
            new CreateCustomer(
                CustomerId.Of(userRegistered.CustomerId),
                userRegistered.IdentityId,
                userRegistered.Username,
                userRegistered.Email
            ),
            cancellationToken
        );
    }
}

@mehdihadeli , your thoughts?

@mehdihadeli
Copy link
Owner

Hi,
Thanks for sending the issue.
Resolving services with IServiceProvider should work for now, but it is not a good practice and we should prevent injecting IServiceProvider directly. Probably the issue is related to my in-memory broker, I will check it.

@mehdihadeli mehdihadeli self-assigned this Mar 17, 2024
@mehdihadeli mehdihadeli added the bug Something isn't working label Mar 17, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

3 participants