-
Notifications
You must be signed in to change notification settings - Fork 71
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
Generate Mediator class that allow for the internal access level on Requests and Handlers / better support for large solutions #79
Comments
It's not possible right now, but I do have an idea that would fit this scenario nicely I think - if we could configure the sourcegenerator to include all the abstractions, then both packages could be as source code and would add no runtime dependencies at all. The closest we can get right now is to have both the source generator and abstractions package added to the project. You could then mark the handlers and messages as internal, but the mediator implementation itself would still be public. We could add an option to make the DI extension method and mediator implementation internal as well I guess, that should not be much work. So options as I see them:
Thoughts? |
I need to familiarize myself with source generators and their limitations; therefore, giving helpful feedback is difficult. It would be great if somebody more knowledgeable were here and could chime in. I initially thought to use your second suggestion:
But with a tiny modification. It would be great if there were an option to configure whether I want to have it all generated as internal or not (with the default being as is - public). It could be done by creating the partial interface with an attribute with a boolean flag.
So, this falls under your third suggestion, where abstractions and implementations are in the same assembly 🙂 |
Deal breaker for me also. I'm building a modular monolith-ish infrastructure and most of my module classes are internal, except for controllers (per module), other communication is done trough message broker. Everything is composed in one API (bootstrap) project where I should be placing source generator package. I get bunch of errors about protection levels. |
Maybe it would be a good idea to enable source generation in project hierarchy. For example, my Application layer has handlers for the business logic, so adding the SourceGenerator dependency to this particular project would generate a partial Mediator implementation with these handlers only. That could be added to the service container using something like |
@ppasieka I also mark my handlers Take a peek or I'm getting it wrong. internal sealed class CreateEventCommandHandler : ICommandHandler<CreateEventCommand, ErrorOr<ApiSuccessResponse>>
{
private readonly ILogger<CreateEventCommandHandler> _logger;
private readonly IEventRepo _eventRepo;
private readonly IMapper _mapper = new Mapper();
private readonly Generate _generate;
private static readonly ActivitySource ActivitySource = new(nameof(CreateEventCommandHandler));
public CreateEventCommandHandler(ILogger<CreateEventCommandHandler> logger,
IEventRepo eventRepo,
IDateTimeProvider dateTimeProvider)
{
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
_eventRepo = eventRepo ?? throw new ArgumentNullException(nameof(eventRepo));
_generate = new Generate(dateTimeProvider);
}
public async ValueTask<ErrorOr<ApiSuccessResponse>> Handle(CreateEventCommand command, CancellationToken cancellationToken)
{
// Start activity
...
}
} |
Hi sorry for being a bit slow.
I'm a bit sceptical of partial generation and stuff like this because (I think) it will lead to more virtual calls and indirection. Perf was one of the main reasons I created this library in that I wanted the overhead from using the pattern to be minimal. Of course, there is already some virtual dispatch in the current impl. anyway, so the impact may not be anything to worry about, so would need some testing/benchmarking to verify. But this is atleast an important consideration to me. Another issue is that I'm not sure this feature (in whatever form it would take) is really worth it, since right now this isn't really a limitation of any specific way this library works, more a fact of how C# works with its access modifiers. The generated |
Greetings, I believe that virtual calls are unnecessary in this scenario. The mediator class generated in the leaf project can directly invoke the I would like to emphasize that this is not a deal-breaker for my use-cases, as I have recently employed your exceptional library in production code without issue. Nevertheless, the ability to generate intermediary implementations would be a welcome addition. Please let me know if you require any further assistance. |
Tracking some improvements around this here: #97 |
I have a project where I would like to keep many concepts marked as internal. It also applies to the mediator 'requests' and 'handlers'. At the moment, I can't use the internal keyword because I'm getting an error:
Is there w way to generate the mediator class as internal? Then, I could completely hide that I'm using the Mediator (it is just an implementation detail) and not expose it from the assembly.
The text was updated successfully, but these errors were encountered: