martinothamar / Mediator

A high performance implementation of Mediator pattern in .NET using source generators.
MIT License
2.16k stars 71 forks source link

Blazor App 2 seperate MediatorDependencyInjectionExtensions (AddMediator) in same namespace, but different assemblies. #152

Open SGStino opened 4 months ago

SGStino commented 4 months ago

In a Blazor App, you have the server side and client side applications where the server side references the client side.

This means, that if Mediator is used in the client-side, it will generate an MediatorDependencyInjectionExtensions class in Microsoft.Extensions.DependencyInjection.

It will then also generate an MediatorDependencyInjectionExtensions in the same namespace of the server assembly, and because it references the client assembly, you get two times the same class name in the same namespace.

Which means it's not possible to use Mediator both on client & server projects? Or am I missing a configuration setting that can be set to change the generation namespace?

MaxLevs commented 4 months ago

Have you reproduced this behavior? Is there a repo with minimal reproduce?

SGStino commented 4 months ago

https://github.com/SGStino/Mediator.BlazorApp-Test

It's far from complete, but the problem already surfaces when you run it, and HTTP GET https://localhost:7070/test/something?request=12345

it returns the response from the client handler instead of the server handler.

{"test":"client generated response for 12345"}

server Handlers/TestServerHandler.cs

    public sealed class TestServerHandler : IRequestHandler<TestRequest, TestResponse>
    {
        public ValueTask<TestResponse> Handle(TestRequest request, CancellationToken cancellationToken)
        { 
            // TODO: do some server side logic here
            return ValueTask.FromResult(new TestResponse("server generated response for " + request.Test));
        }
    }

client Handlers/TestClientHandler.cs

    public sealed class TestClientHandler : IRequestHandler<TestRequest, TestResponse>
    {
        public ValueTask<TestResponse> Handle(TestRequest request, CancellationToken cancellationToken)
        {
            // TODO: forward request to API;
            return ValueTask.FromResult(new TestResponse("client generated response for " + request.Test));
        }
    }

while the minimal api call shouldn't be touching the client side handler.

The idea is that the client side handler should forward the request to the server api call, and there run the serverside logic (access database, authorization, ...)

But because the server assembly needs to reference the client assembly for blazor to work, And since both AddMediator extension methods are in the same namespace, it's the compiler that seems to decide which one to use?

SGStino commented 4 months ago

Oh, i forgot to add the source generator to the server side project. There was no server side AddMediator.

When there is one, it does exactly as i expected:

Error (active)  CS0121  The call is ambiguous between the following methods or properties: 'Microsoft.Extensions.DependencyInjection.MediatorDependencyInjectionExtensions.AddMediator(Microsoft.Extensions.DependencyInjection.IServiceCollection, System.Action<Mediator.MediatorOptions>)'