2014-12-16 36 views
12

Mam dwa interfejsy:rejestracji „pół-zamknięte” rodzajowy składnik

public interface IQuery<TResult> { } 

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

Przykładem zamkniętego realizacji 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); 
    } 
} 

mogę się zarejestrować i rozwiązania zamknięte rodzajowe implementacje IQueryHandler<,> z rejestracja tego komponentu:

Classes.FromAssemblyContaining(typeof(IQueryHandler<,>)) 
    .BasedOn(typeof(IQueryHandler<,>)) 
    .WithServiceAllInterfaces() 

Jednak to, co chciałbym robić to rozwiązać otwartą implementację generycznym „przymknięte” (czyli określa ogólny parametr TQuery typ):

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); 
    } 
} 

Kiedy próbowałem rozwiązać IQueryHandler<GetById<Event>, Event> mam ten wyjątek:

wyjątek typu "Castle.MicroKernel.Handlers.GenericHandlerTypeMismatchException" wystąpił w pliku Castle.Windsor.dll, ale nie było obsługiwane w kodzie użytkownika

Dodatkowe informacje: typy zapytań.GetById'1 [[Models.Event, Domain, Version = 1.0.0.0, Culture = neutral, PublicKeyTok en = null]], Models.Event nie spełniają ogólnych ograniczeń typu implementacji Queries.GetByIdHandler'1 składnika 'Queries.GetByIdHandler'1'. Jest to najprawdopodobniej błąd w twoim kodzie.

Wygląda typ został pomyślnie zarejestrowany, a ograniczenia są spełnione w miarę mogę powiedzieć (Event jest klasa i wdraża IIdentity). Czego tu mi brakuje? Czy próbuję zrobić coś, z czym Windsor nie może sobie poradzić?

Odpowiedz

5

(nie jestem delegowania to jako odpowiedź, tak jak kilka przydatnych informacji, że jest zbyt dużo informacji o komentarz.)

Chociaż ten kod w zamku nie:

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>>(); 
} 

to samo w Simple Injector prac:

public void GetInstance_GetByIdHandler_Succeeds() 
{ 
    var container = new SimpleInjector.Container(); 

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

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

Dzięki, wygląda na to, że jest to problem z Windsoru następnie – AlexFoxGill

+1

mam badane dalej i myślę, że masz rację, tak jest to poprawna answe r: Windsor nie może tego zrobić. Simple Injector wygląda coraz lepiej dla mojego projektu – AlexFoxGill