Caliburn.Micro icon indicating copy to clipboard operation
Caliburn.Micro copied to clipboard

Implementation of IHandle<T> for synchronous handlers

Open anuviswan opened this issue 4 years ago • 6 comments

In earlier versions of Caliburn Micro, we used to have separate implementations of IHandle (and IHandleWithTask). However, in 4.x, this seems to be changed and replaced with a single interface.

public interface IHandle<TMessage>
{
       Task HandleAsync(TMessage message, CancellationToken cancellationToken);
}

One issue I find with this approach is that in the scenarios when there are no asynchronous calls in the handlers, the naming convention looks out of place with the Async suffix. The code style checkers would show these as warnings as well, leaving a clutter of warnings in the solution.

Wouldn't it be better to bring back the IHandleWithTask to separate the different implementations ?

anuviswan avatar Oct 10 '21 05:10 anuviswan

I am not sure why the interface was removed and put into IHandle but I think that it was mainly because the focus for 4.0 was async.

I do like the idea of being able to choose whether to be async or not, not sure if it would cause any issues to reinstate the original interface. Aside from the breaking changes that is.

KasperSK avatar Oct 10 '21 20:10 KasperSK

If we change IHandle back to the way it was that would be another breaking change. I wonder if would be better to add IHandleWithOutTask interface for people who do not want to use async

vb2ae avatar Oct 12 '21 09:10 vb2ae

Two separate interfaces has its own problems though - what if a subscriber class implements both the interfaces ? Should both handlers be executed ? If yes, which handler would have priority and should be executed first ?

anuviswan avatar Oct 12 '21 10:10 anuviswan

That is a good point. I guess we could put both the async and sync into IHandle

vb2ae avatar Oct 12 '21 10:10 vb2ae

I don't think putting both functions into IHandle is an option because then users are forced to implement one no-op for each handler (unless I misunderstood the suggestion?). To the original point, in scenarios with no asynchronous calls, code style checkers should only show a warning if the async keyword is used. Setting the handler as the following should work fine:

public Task HandleAsync(MyEvent @event, CancellationToken cancellationToken)
{
    // Handle event
    return Task.CompletedTask;
}

Jammyo avatar Oct 15 '21 10:10 Jammyo

C#8 has support to add default implementations to methods. Updated the IHandle interface to add have default implementation for .net 5, .net 6, and .net core 3.1 #780

vb2ae avatar Oct 24 '21 20:10 vb2ae