Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

CQRS Query handler with no parameter

public interface IQueryHandler<in TQuery, out TResult>
    where TQuery : IQuery<TResult>
{
    TResult Handle(TQuery query);
}

This is a query handler interface that requires a parameter to execute query.

public class PlaceByIdHandler : IQueryHandler<PlaceById, PlaceModel>
{
    ...........

    public PlaceModel Execute(PlaceById query)
    {
        return repository.Query<PlaceModel>("select * from places where id="+ query.id);
    }
}

But some queryies does not need parameter. For example Get all places:

public class PlaceAllHandler : IQueryHandler<PlaceAll, PlaceModel>
{
    ..........

    public PlaceModel Execute(PlaceAll query)
    {
        return return repository.Query<PlaceModel>("select * from places");
    }
}

But now PlaceAll is a class that has no Member.

public class PlaceAll{}

Is this a true approach? Is there any order?

like image 625
barteloma Avatar asked Sep 29 '22 14:09

barteloma


2 Answers

But some queries does not need parameter.

Additional parameters/properties on a query are optional.

Your query PlaceAll (I would call it AllPlaces) has all information. If query handler doesn't need any additional parameters to Handle the query then you do not need to specify them.

I expect that you use the following IQuery<TResult> interface:

public interface IQuery<TResult> 
{  }

As you can see it doesn't have any parameters as well. QueryHandler depends on a type of the query (TQuery or IQuery<TResult>) only.

like image 111
Ilya Palkin Avatar answered Oct 03 '22 21:10

Ilya Palkin


I guess you could infer my answer from the others:

You have two options here. You could use the null object pattern of sorts. This is similar to your PlaceAll class but should just be generic to always represent 'all' results. So perhaps something like AllResults would suffice. Now you don't need an AllCities, AllSomething, etc.

The other way is to have a more explicit interface role. You already have one that takes a parameter. You could add the other without the parameter as Ilya has demonstrated:

public interface IQueryHandler<TQuery, TResult> {}

public interface IQueryHandler<TResult> {}

However, you may need to cast/safe cast the object to use this.

Since most queries are rather specific to their use cases I have my doubts about the usefulness of such generic query interfaces, though :)

like image 37
Eben Roux Avatar answered Oct 03 '22 22:10

Eben Roux