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

Add Support for Generic Handlers #1013

Merged
merged 4 commits into from
Jun 6, 2024
Merged

Conversation

zachpainter77
Copy link
Contributor

@zachpainter77 zachpainter77 commented Mar 23, 2024

This PR essentially adds the required logic to register open generic request handlers.

For example:

//class to use as generic request type parameter
public class Pong
{
    string Message? { get; set; }
}

//generic request definition
public class GenericPing<T> : IRequest<T>
    where T : Pong 
{
    public T? Pong { get; set; }
}

//generic request handler
public class GenericPingHandler<T> : IRequestHandler<GenericPing<T>, T>
    where T : Pong
{
    public Task<T> Handle(GenericPing<T> request, CancellationToken cancellationToken) => Task.FromResult(request.Pong!);
}

//usage
var pong = _mediator.Send(new GenericPing<Pong>{ Pong = new() { Message = "Ping Pong" } });
Console.WriteLine(pong.Message); //would output "Ping Pong"

Huge fan of this library.. With that said.. I find it kind of tedious to have to create separate handlers for each thing, when the code is pretty much copy paste. Just the entity or type I'm working with has changed. I think it would be much easier to work with if we could essentially cut some corners by leveraging c# generics.

The only way you can do this without needing a third party library is use assembly scanning and register every single concrete implementation of the generic handlers. So that is what the code is doing.

I also added some tests to ensure the handlers were being registered.

**Note: this feature doesn't introduce any breaking changes. The feature is simply opt in by creating handlers like above.. if you don't want to use them then you can keep on using the library the same way without any hiccups.

@zachpainter77
Copy link
Contributor Author

zachpainter77 commented Apr 16, 2024 via email

@kevingates
Copy link

Looks like a neat, new feature. I'd like to see additional documentation with more practical examples, but I think this is neat.

@zachpainter77
Copy link
Contributor Author

@jbogard , are there any more changes necessary for this I think I converted the tests to use the default .net container and removed the dependency on Lamar like you suggested. Just wondering if anything else was needed.

Thanks.

@jbogard jbogard merged commit 3b8bf44 into jbogard:master Jun 6, 2024
1 check passed
@jbogard
Copy link
Owner

jbogard commented Jun 6, 2024

@zachpainter77 if you have time, can you add an example in the wiki?

@zachpainter77
Copy link
Contributor Author

zachpainter77 commented Jun 6, 2024 via email

oskogstad added a commit to digdir/dialogporten that referenced this pull request Jun 16, 2024
[![Mend
Renovate](https://app.renovatebot.com/images/banner.svg)](https://renovatebot.com)

This PR contains the following updates:

| Package | Change | Age | Adoption | Passing | Confidence |
|---|---|---|---|---|---|
| [MediatR](https://togithub.com/jbogard/MediatR) | `12.2.0` -> `12.3.0`
|
[![age](https://developer.mend.io/api/mc/badges/age/nuget/MediatR/12.3.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![adoption](https://developer.mend.io/api/mc/badges/adoption/nuget/MediatR/12.3.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![passing](https://developer.mend.io/api/mc/badges/compatibility/nuget/MediatR/12.2.0/12.3.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![confidence](https://developer.mend.io/api/mc/badges/confidence/nuget/MediatR/12.2.0/12.3.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|

---

### Release Notes

<details>
<summary>jbogard/MediatR (MediatR)</summary>

###
[`v12.3.0`](https://togithub.com/jbogard/MediatR/releases/tag/v12.3.0)

#### What's Changed

- Fix AutoRegisterRequestProcessors to include all implementations by
[@&#8203;hisuwh](https://togithub.com/hisuwh) in
[jbogard/MediatR#989
- [#&#8203;1016](https://togithub.com/jbogard/MediatR/issues/1016) Use
repo readme for base package by
[@&#8203;thompson-tomo](https://togithub.com/thompson-tomo) in
[jbogard/MediatR#1017
- Add Support for Generic Handlers by
[@&#8203;zachpainter77](https://togithub.com/zachpainter77) in
[jbogard/MediatR#1013

#### New Contributors

- [@&#8203;hisuwh](https://togithub.com/hisuwh) made their first
contribution in
[jbogard/MediatR#989
- [@&#8203;thompson-tomo](https://togithub.com/thompson-tomo) made their
first contribution in
[jbogard/MediatR#1017
- [@&#8203;zachpainter77](https://togithub.com/zachpainter77) made their
first contribution in
[jbogard/MediatR#1013

**Full Changelog**:
jbogard/MediatR@v12.2.0...v12.3.0

</details>

---

### Configuration

📅 **Schedule**: Branch creation - "before 7am on Sunday,before 7am on
Wednesday" (UTC), Automerge - At any time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you
are satisfied.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the
rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update
again.

---

- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check
this box

---

This PR has been generated by [Mend
Renovate](https://www.mend.io/free-developer-tools/renovate/). View
repository job log
[here](https://developer.mend.io/github/digdir/dialogporten).

<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzNy4zOTMuMCIsInVwZGF0ZWRJblZlciI6IjM3LjM5My4wIiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6W119-->

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Ole Jørgen Skogstad <skogstad@softis.net>
@hisuwh
Copy link
Contributor

hisuwh commented Jun 27, 2024

@zachpainter77

**Note: this feature doesn't introduce any breaking changes. The feature is simply opt in by creating handlers like above.. if you don't want to use them then you can keep on using the library the same way without any hiccups.

Unfortunately, this assumption is incorrect. I'm getting an error on startup with the latest version:
image

It would seem this is incompatible with some code I already have for handling Open Generic Handlers.

The only way you can do this without needing a third party library is use assembly scanning and register every single concrete implementation of the generic handlers. So that is what the code is doing.

This is a slight misnomer. You DI tool likely has a way to handle this - which is what I'm doing, using a fallback policy to catch missing open handlers and close them.


I think the main problem is you are only handling a single generic argument here: https://github.com/jbogard/MediatR/pull/1013/files#diff-c4d1d5960b86a86bee0fd5974803c90f8656cde09914a4c43ae14dc193c3cf35R195

But my handlers have multiple.

@zachpainter77
Copy link
Contributor Author

@hisuwh

Yes, you are absolutely correct.. I found out about this a while back (#1038 ) and have been working on a fix but haven't had time until today. So I have pushed a pull request out that fixes it and adds some extensive testing.. But there could be more to discuss. Can you please review it if you have time?

PR -> #1048

@hisuwh
Copy link
Contributor

hisuwh commented Jul 5, 2024

I'm away from my computer today but I'll try and review it in the next few days.

@grosch-intl
Copy link

Any updates here? Upgrading to this version breaks the project.

@zachpainter77
Copy link
Contributor Author

Any updates here? Upgrading to this version breaks the project.

There is a PR to fix the breaking change.. here: #1048

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants