jbogard / MediatR

Simple, unambitious mediator implementation in .NET
Apache License 2.0
10.91k stars 1.16k forks source link

How do I register custom interfaces with MediatR? #951

Closed jscarle closed 11 months ago

jscarle commented 11 months ago

I tried searching past issues and the documentation, but I couldn't find a clear answer.

I have the following interfaces in my application:

public interface ICommand<out TResult> : IOperation<TResult> { }
public interface ICommand : IOperation { }
public interface ICommandHandler<in TCommand> : IOperationHandler<TCommand>
    where TCommand : ICommand
{ }
public interface ICommandHandler<in TCommand, TResult> : IOperationHandler<TCommand, TResult>
    where TCommand : ICommand<TResult>
{ }

public interface IQuery<out TResult> : IOperation<TResult> { }
public interface IQuery : IOperation { }
public interface IQueryHandler<in TQuery> : IOperationHandler<TQuery>
    where TQuery : IQuery
{ }
public interface IQueryHandler<in TQuery, TResult> : IOperationHandler<TQuery, TResult>
    where TQuery : IQuery<TResult>
{ }

internal interface IOperation<out TResult> { }
internal interface IOperation { }
internal interface IOperationHandler<in TOperation>
    where TOperation : IOperation
{ }

internal interface IOperationHandler<in TOperation, TResult>
    where TOperation : IOperation<TResult>
{ }

How could I use those interfaces instead of the built-in IRequest, IRequestHandler with MediatR?

ICommand/ICommandHandler and IQuery/IQueryHandler are what I'd like to send/use with MediatR? IOperation/IOperationHandler are used as markers.

jbogard commented 11 months ago

You don't. If you want to use your own interfaces, you're better off forking MediatR and renaming what's there.

I never plan to support "bring-your-own-interfaces" since most folks that ask that are in some pursuit of Clean or whatever architecture, and I vehemently oppose such pursuits of "domain can't reference other libraries" sorts of thing. Not suggesting it's what you're asking for but people abuse my libraries enough already, I'm not gonna make it easier šŸ˜œ

jscarle commented 11 months ago

Right, I can understand that. Of course, people that advocate that domain cannot reference "any" other library are a bit extremist. There are merits to separating your code in layers, but most of us are flexible where it makes senses. For example Jason Taylor, a well known advocate for Clean Architecture, himself references MediatR at the domain level in his example. The irony is that, although you vehemently oppose such pursuits, MediatR is probably the most reference library for exactly this use case.

The MediatR.Contracts library solves the issue at the domain level, however it doesn't include interfaces needed at the application level. Any chance that interfaces such as IMediator, IRequestHandler, and INotificationHandler could one day migrate to the Contracts library?

jbogard commented 11 months ago

Ah. Then no. The point of the Contracts library is NOT for solving Clean/Onion/Hexagonal architectural constraints. It's for when you're sharing the request contracts, usually in a package, across applications or systems.

This has been discussed a few times here, but no, I would never move the handlers to a separate package to try to satisfy those architectural constraints. Why not ask Microsoft to move the IList<T> interface to a separate Contracts assembly from List<T>? The logic for that argument is the same.

jscarle commented 11 months ago

I understand. Thanks for you time nonetheless. šŸ‘šŸ»