我有两个接口:

public interface IQuery<TResult> { }

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

iqueryhandler的封闭实现示例:
public class EventBookingsHandler : IQueryHandler<EventBookings, IEnumerable<EventBooking>>
{
    private readonly DbContext _context;

    public EventBookingsHandler(DbContext context)
    {
        _context = context;
    }

    public IEnumerable<EventBooking> Handle(EventBookings q)
    {
        return _context.Set<MemberEvent>()
            .OfEvent(q.EventId)
            .AsEnumerable()
            .Select(EventBooking.FromMemberEvent);
    }
}

通过这个组件注册,我可以注册和解析IQueryHandler<,>的封闭通用实现:
Classes.FromAssemblyContaining(typeof(IQueryHandler<,>))
    .BasedOn(typeof(IQueryHandler<,>))
    .WithServiceAllInterfaces()

不过,我想做的是解析一个“半封闭”的开放泛型实现(即指定一个泛型TQuery类型参数):
public class GetById<TEntity> : IQuery<TEntity> where TEntity : class, IIdentity
{
    public int Id { get; private set; }

    public GetById(int id)
    {
        Id = id;
    }
}

public class GetByIdHandler<TEntity> : IQueryHandler<GetById<TEntity>, TEntity> where TEntity : class, IIdentity
{
    private readonly DbContext _context;

    public GetByIdHandler(DbContext context)
    {
        _context = context;
    }

    public TEntity Handle(GetById<TEntity> q)
    {
        return _context.Set<TEntity>().Find(q.Id);
    }
}

当我试图解决IQueryHandler<GetById<Event>, Event>时,我得到了一个异常:
“CARS.MICKEngult.TraseReal.GrimeActurLeTimeMeMatHutExpExtExchange”的例外情况发生在Castle.Windsor.dll中,但未在用户代码中处理
其他信息:类型查询。getbyid'1[[models.event,domain,version=1.0.0.0,culture=neutral,publickeytoken=null]],模型。事件不满足实现类型查询的一般约束。组件“querys.getbyidhandler'1”的getbyidhandler'1。这很可能是代码中的一个错误。
看起来这个类型已经成功注册了,根据我可以说,满足了约束(Event是一个类并实现IIdentity)。我错过了什么?我想做温莎无法应付的事情吗?

最佳答案

(我并不是把这个作为一个答案,只是一些有用的信息,这些信息太多了,不适合发表评论。)
当Castle中的代码失败时:

public void Resolve_GetByIdHandler_Succeeds()
{
    var container = new Castle.Windsor.WindsorContainer();

    container.Register(Component
        .For(typeof(IQueryHandler<,>))
        .ImplementedBy(typeof(GetByIdHandler<>)));

    var x = container.Resolve<IQueryHandler<GetById<Event>, Event>>();
}

Simple Injector中的相同功能:
public void GetInstance_GetByIdHandler_Succeeds()
{
    var container = new SimpleInjector.Container();

    container.RegisterOpenGeneric(
        typeof(IQueryHandler<,>),
        typeof(GetByIdHandler<>));

    var x = container.GetInstance<IQueryHandler<GetById<Event>, Event>>();
}

08-25 02:22