Register decorator with open generics

197 Views Asked by At

I was hoping to get some feedback on how to register decorators for some specific contracts and implementations. Here is what i have

A marker query interface like such

public interface IQueryBase
{

}

A query handler contract like such

   public interface IQueryHandlerNew<TQuery, TResult>
  where TQuery : IQueryBase
{
    TResult Handle(TQuery request);
    Task<TResult> HandleAsync(TQuery request);
}

A actual query like such

public sealed class FindCitiesByCountryIdQuery : IQueryBase
{
    public int PageNumber { get; set; }
    public int CountryId { get; set; }
    public int PageSize { get; set; }
}


public class CityReadModel
{
    public int CityId { get; set; }
    public string CityName { get; set; }
}

And finally the queryhandler like such

   public class FindCitiesByCountryIdQueryHandler : IQueryHandlerNew<FindCitiesByCountryIdQuery, CityReadModel[]>
{
    public CityReadModel[] Handle(FindCitiesByCountryIdQuery request)
    {
        throw new NotImplementedException();
    }

    public Task<CityReadModel[]> HandleAsync(FindCitiesByCountryIdQuery request)
    {
        throw new NotImplementedException();
    }
}

Here is my loggingdecorator for the queryhandlers

 public class QueryHandlerLogginDecorator2<TQuery, TResult> : IQueryHandlerNew<TQuery, TResult> where TQuery : IQueryBase
{
    private readonly IQueryHandlerNew<TQuery, TResult> _decoratee;
    private readonly ICustomLogger _logger;

    public QueryHandlerLogginDecorator2(IQueryHandlerNew<TQuery, TResult> decoratee, ICustomLogger logger)
    {
        _decoratee = decoratee;
        _logger = logger;
    }

    public TResult Handle(TQuery request)
    {
        try
        {
            //Log request information here 
            return _decoratee.Handle(request);
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, string.Format(LogConstants.ErrorLogFormat, DateTime.UtcNow, GetType(), ex.Message));
            throw;
        }
    }

    public Task<TResult> HandleAsync(TQuery request)
    {
        try
        {
            //Log request information here 
            return _decoratee.HandleAsync(request);
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, string.Format(LogConstants.ErrorLogFormat, DateTime.UtcNow, GetType(), ex.Message));
            throw;
        }
    }
}

When i try to register this setup using simpleinjector register decorator like such

container.RegisterDecorator(typeof(IQueryHandlerNew<>), typeof(QueryHandlerLogginDecorator2<>), Lifestyle.Transient);

it fails and says "Using IQueryHandlerNew requires 2 type arguments"

i use a similar setup to register decorators with 1 type argument (for example for a repository) and it registers just fine.

not sure what i am doing wrong here. are there known limitations with simpleinjector and registering decorators with more than 1 type arguments?

0

There are 0 best solutions below