What are some of the benefits of this approach compared to calling an interface of your services returning Task<T> if needed from you controller?
Some of the benefits of this in my view is:
- Clear view of how many dependencies a controller has, though the dependencies are abstractions
- Easy to Control+Click into the service in your IDE.
- Easy to "Find all usages" of the service.
- Easy to mock in unit tests, just mock the interface
- Can be decorated if needed with Scrutor
- Fast, just a method call
- Leverages Task if async is required, easy to e.g. call a service get id returned to use to call another service.
How would you do these things with ChannelWriter and ChannelReader, do you have an example of this approach somewhere?
I'm glad you asked, because I should clarify that my use case is "fire and forget" tasks. The controller is not interested in the result of the service's operation, so there is no need for any return value.
Regarding your other points:
Dependencies can be traced by the job type associated with the channel. It is somewhat indirect but no more indirect than an interface, really.
Since I am not concerned with results, mocking is even easier. I just have a service implementation that consumes from a ChannelReader and discards the result. This is really a single class since it can take a type parameter if that makes sense--no need for separate mocks.
I haven't used Scrutor, so I can't speak to that.
Reading and writing from a channel are also just method calls. There are synchronous and asynchronous options for both.
I don't have any open code to share, but I found the design very intuitive. If you read the documentation and follow your intuition, you will probably implement things exactly as I did.
Also I am not trying to convince anyone that channels are the best answer! I just found them helpful in my projects and think they have not been promoted very well in the .NET sphere.
Some of the benefits of this in my view is: - Clear view of how many dependencies a controller has, though the dependencies are abstractions - Easy to Control+Click into the service in your IDE. - Easy to "Find all usages" of the service. - Easy to mock in unit tests, just mock the interface - Can be decorated if needed with Scrutor - Fast, just a method call - Leverages Task if async is required, easy to e.g. call a service get id returned to use to call another service.
How would you do these things with ChannelWriter and ChannelReader, do you have an example of this approach somewhere?