Optimize Generic Handler Registration in MediatR#1093
Optimize Generic Handler Registration in MediatR#1093zachpainter77 wants to merge 2 commits intoLuckyPennySoftware:masterfrom
Conversation
Summary This PR introduces an optimized mechanism for registering generic handlers in MediatR. The current implementation scans all assemblies passed to MediatR during startup to find every possible concrete implementation and service type that satisfies all generic handler constraints. This PR modifies the behavior to scan and register generic handler services on-demand, triggered only when a specific service is requested. This feature remains opt-in and can be enabled by setting the RegisterGenericHandlers configuration flag to true. Changes Made Optimized Generic Handler Registration: The registration process now scans assemblies only when a specific service is requested, rather than eagerly scanning all possible types during startup. Once a service is resolved, the registration is cached for future requests. Dynamic Service Provider Integration: Introduced dynamic resolution and caching for generic handlers, minimizing the startup overhead. Backward Compatibility: The feature remains optional and is controlled via the RegisterGenericHandlers flag in the MediatR configuration. Code Refactor: Extracted and modularized key logic for resolving generic handler types. Improved readability and maintainability by reducing redundant logic and clarifying workflows.
|
I'm just a random passerby who has used MediatR in the past, but I don't think this improvement is worth adding a whole new dependency to the core: While it's fine to have the abstraction since the majority of people use it with ASP.NET Core anyway, there are some niche cases where people use MediatR with other DI containers (like SimpleInjector) and the app doesn't have the MSFT DI. In these cases, this MSFT dependency will be an unnecessary burden. Again, this isn't the end of the world, but it's not listed as a con. There's also some dead code: This part also never can be |
- remove property with no reference - remove commented out code - remoce redundant check for null open interface type
Thanks for your review! much appreciated! I have fixed the following issues...
I hear what you are saying with the dependency, however, the library is already dependent upon So I'll update the description / summary to include this as a con. But I don't really see how it could that much of a burden for anyone currently using this with another container. Edit: But if it absolutely cannot have this dependency then I can take a crack at creating a custom implementation that could possibly be used as replacement to the defined Again, Thank you for taking the time to review much appreciated. Cheers. |
|
Right on time, I'm looking forward this PR. Once I finish my assessments and land a job(hope to), I wanna help with this. @zachpainter77 theres anything that I can help you with? |
|
Not at the moment but stay tuned I guess 😊
…On Thu, Jan 30, 2025, 4:06 PM Felipe Nunes ***@***.***> wrote:
Right on time, I'm looking forward this PR.
Once I finish my assessments and land a job(hope to), I wanna help with
this.
@zachpainter77 <https://github.com/zachpainter77> theres anything that I
can help you with?
—
Reply to this email directly, view it on GitHub
<#1093 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/ACL2QUXMLBS4YWZNLY4ZEMD2NK5ARAVCNFSM6AAAAABVKZI4FOVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDMMRVHE4DONRUG4>
.
You are receiving this because you were mentioned.Message ID:
***@***.***>
|
|
This PR is stale because it has been open 28 days with no activity. Remove stale label or comment or this will be closed in 14 days. |
|
not stale.. This pr implements the on demand generic handler registration that @jbogard was looking for. |
|
Sorry haven't forgotten about this one, just busy with day job |
No worries! understandable. :) |
|
I think this is on the right track but still has some issues. The I'm not sure what issues would arise from the additional dependency. Maybe some extra types show up in IntelliSense? |
Hmm.. I'm not quite sure I understand what you mean.. The implementation looks for a dependency and if it is not found using the default container it then checks the custom container. If the types are found it activates and resolves the dependency. If not then it adds it to the custom service provider and stores the registration for future use. This in my understanding is cached. So it only calls EDIT: AHHH!! ok ok I see what you mean now! I will work on this as soon as I get a chance! |
|
This PR is stale because it has been open 28 days with no activity. Remove stale label or comment or this will be closed in 14 days. |
|
Haven't had time to work on this quite yet. Keeping the pr alive with
comment.
…On Tue, Apr 22, 2025, 5:07 AM github-actions[bot] ***@***.***> wrote:
This PR is stale because it has been open 28 days with no activity. Remove
stale label or comment or this will be closed in 14 days.
—
Reply to this email directly, view it on GitHub
<#1093 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/ACL2QUXW5KGRGFI6ZDZKDVD22YWIRAVCNFSM6AAAAABVKZI4FOVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDQMRRGEZDAMZWGE>
.
You are receiving this because you were mentioned.Message ID:
***@***.***>
*github-actions[bot]* left a comment (LuckyPennySoftware/MediatR#1093)
<#1093 (comment)>
This PR is stale because it has been open 28 days with no activity. Remove
stale label or comment or this will be closed in 14 days.
—
Reply to this email directly, view it on GitHub
<#1093 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/ACL2QUXW5KGRGFI6ZDZKDVD22YWIRAVCNFSM6AAAAABVKZI4FOVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDQMRRGEZDAMZWGE>
.
You are receiving this because you were mentioned.Message ID:
***@***.***>
|
|
one thing I noticed is that if you got IMediator as transient/scoped and the DynamicServiceProvider gets created each time and does not cache |
|
This PR is stale because it has been open 28 days with no activity. Remove stale label or comment or this will be closed in 14 days. |
|
If anyone would like to tackle this issue be my guest. I've been quite busy
lately.
…On Wed, May 14, 2025, 10:59 AM neko_code ***@***.***> wrote:
*luckyycode* left a comment (LuckyPennySoftware/MediatR#1093)
<#1093 (comment)>
one thing I noticed is that if you got IMediator as transient/scoped and
the DynamicServiceProvider gets created each time and does not cache
—
Reply to this email directly, view it on GitHub
<#1093 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/ACL2QUX3BGCZ3HFSJUJJ3ED26OABVAVCNFSM6AAAAABVKZI4FOVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDQOBRGA4DEOJUGE>
.
You are receiving this because you were mentioned.Message ID:
***@***.***>
|
|
|
Arnab-Developer
left a comment
There was a problem hiding this comment.
I was looking into the code changes and have one question which I have asked here. I am not too much familiar with the codebase, so may be my question makes no sense.
| public MyCustomMediator(IServiceProvider provider) { } | ||
| public MyCustomMediator(IServiceProvider provider, INotificationPublisher publisher) { } |
There was a problem hiding this comment.
You have added parameters (provider and publisher) in the constructor, but those parameters don't have any usage! Why is it needed?
|
Closing this pull request I have no wish to contribute to this library now that it is becoming commercial. |
Ok @jbogard I know how much you disliked the eager loading strategy of the first generic handler registration implementation, so I took a shot at making a lazy loaded implementation that only scans the assembly when you request a generic handler service that is not already registered. This on demand approach seems to be exactly what you were describing to me. Please review. :)
Summary
This PR introduces an optimized mechanism for registering generic handlers in
MediatR. The current implementation scans all assemblies passed toMediatRduring startup to find every possible concrete implementation and service type that satisfies all generic handler constraints. This PR modifies the behavior to scan and register generic handler services on-demand, triggered only when a specific service is requested.This feature remains opt-in and can be enabled by setting the
RegisterGenericHandlersconfiguration flag to true.Changes Made
Optimized Generic Handler Registration:
Dynamic Service Provider Integration:
Backward Compatibility:
RegisterGenericHandlersflag in theMediatRconfiguration.Code Refactor:
ServiceRegistrarlogic used for previous eager loading of generic handlers.Pros
Improved Performance:
Lower Memory Overhead:
IServiceCollectionsince only required services are registered.Scalability:
Maintains Flexibility:
RegisterGenericHandlers, ensuring no impact on existing applications unless explicitly enabled.Compatibility:
Cons
Potential Runtime Costs:
Increased Complexity:
Microsoft.Extensions.DependencyInjection)Conclusion
This PR significantly optimizes the generic handler registration process, making it more efficient and scalable while maintaining backward compatibility. By deferring the registration of generic handlers to runtime and caching them for subsequent use, it strikes a balance between performance and flexibility.