Utworzenie nowego interfejsu, który dziedziczy po IRequestHandler

0

Mam sobie interfejs ICommand, który dziedziczy po IRequest.
Chciałbym sobie przygotować takie coś jak ICommandHandler co by działało tak jak IRequestHandler.

Poniżej przykład tego jak ja sobie to wyobrażam...

public interface ICommandHandler<TCommand, TResult> : IRequestHandler<TCommand, TResult> where TCommand : class,  ICommand<TResult>
    {
        Task<TResult> Handle(TCommand command);
    }

Pozostaje tylko kwestia jak to zrobić żeby metoda Handle w interfejsie ICommandHandler realizowała to co metoda Handle w interfejsie IRequestHandler i żeby obsłużył ją MediatR?

3

Ostatnio znalazłem tu na forum wątek w którym ktoś właśnie coś takiego robił: Moja implementacja DDD w C#
Pytanie tylko czy oprócz nazwy coś Ci to daje? Dla mnie to trochę zbędny wrapper na MediatR

1
altek napisał(a):

Pozostaje tylko kwestia jak to zrobić żeby metoda Handle w interfejsie ICommandHandler realizowała to co metoda Handle w interfejsie IRequestHandler i żeby obsłużył ją MediatR?

Takie rzeczy jedynie z klasą abstrakcyjną. Bo rozumiem, że chodzi o pozbycie się cancellationToken z metody Handle(TRequest request, CancellationToken cancellationToken)? Jeśli nie i chodzi o zmianę nazwy z IRequest na ICommand i z IRequestHandler na ICommandHandler to wyrzuć całkowicie metodę z interfejsu ICommandHandler. Choć jak napisał @szydlak nie widzę w tym sensu.

szydlak napisał(a):

Ostatnio znalazłem tu na forum wątek w którym ktoś właśnie coś takiego robił: Moja implementacja DDD w C#

Ja zastosowałem takie rozwiązanie, żeby opakować TResponse w Response<TResponse> na potrzeby obsługi blędów. A klasę Response wziąłem z tego posta.

public interface ICommandHandler<in TCommand, TData> : IRequestHandler<TCommand, Response<TData>> 
    where TCommand : ICommand<TData>
    where TData : class
{
}

Dzięki temu mogłem użyć:

internal class SomeCommandHandler : ICommandHandler<SomeCommand, SomeViewModel>
{
    // ...
}

zamiast:

internal class SomeCommandHandler : IRequestHandler<SomeCommand, Response<SomeViewModel>>
{
    // ...
}
0

To taka trochę moja zachciewajka, że zamiast "Handle(TRequest request, CancelationToken cancelationToken)" chcę mieć "Handle(TCommand command)".

2

To tak jak pisałem jedynie z klasą abstrakcyjną można zrobić.

public abstract class CommandHandler<TCommand, TResult> : IRequestHandler<TCommand, TResult> 
    where TCommand : class,  ICommand<TResult>
{
    protected abstract Task<TResult> Handle(TCommand command);

    public Task<TResult> Handle(TCommand request, CancellationToken cancellationToken)
    {
        // ignore cancellationToken
        return Handle(request);
    }
}
0

Stosując klasę abstrakcyjną tak jak zaproponowałeś jakim cudem wykona się metoda "public...Handle" skoro w docelowym handlerze nadpisujemy metodę "protected...Handle"?

1
altek napisał(a):

Stosując klasę abstrakcyjną tak jak zaproponowałeś jakim cudem wykona się metoda "public...Handle" skoro w docelowym handlerze nadpisujemy metodę "protected...Handle"?

Nie za bardzo rozumiem dlaczego miałaby się nie wykonać. Przepływ sterowania będzie mniej więcej taki (w skrócie, nie dosłownie):

gdzieś tam:

await mediator.Send(someCommand);

w mediatorze:

foreach (var handler in matchingHandlers)
{
    await handler.Handle(request, cancellationToken);
}

w CommandHandler.cs:

await this.Handle(request); // execution of abstract method

w SomeCommandHandler.cs:

// overriding abstract method
protected override async Task<TResult> Handle(TCommand command)
{
    // ... your code
}
0

Rozumiem, że publiczna metoda Handle jest tylko po to aby zaimplementować metodę z interfejsu IRequestHandler?
W zamyśle nie będzie używana ?

1
altek napisał(a):

Rozumiem, że publiczna metoda Handle jest tylko po to aby zaimplementować metodę z interfejsu IRequestHandler?

W zamyśle nie będzie używana ?

Przez ciebie nie, ale przez mediator będzie. Mediator "nie wie", że utworzyłeś sobie inną metodę Handle(TCommand command) i on zna tylko Handle(TRequest request, CancellationToken cancellationToken). Inaczej mówiąc: mediator wszystkie handlery obsługuje za pomocą interfejsu IRequestHandler<TRequest, TResponse> i jego metody Handle.

1 użytkowników online, w tym zalogowanych: 0, gości: 1