I have a CQRS architecture which, on the query side has a QueryDefinition class and for each of them a QueryHandler class.

I had been wiring them up 1-1 in a configuration file but I would rather use some sort of auto-discovery for example the nugget package UnityConfiguration.

How do I configure it such that when a QueryHandler is created if that handler requires one or more repository classes they will be instantiated and passed into the constructor?

For example - my query handler for the "Get all clients" query would look something like:-


vb.net Code:
  1. Imports TaskBazaar.Query
  2. Imports TaskBazaar.Repository
  3.  
  4. Namespace Handlers
  5.     Public Class GetActiveClientsQueryHandler
  6.         Implements IQueryHandler(Of Definitions.GetActiveClientsQueryDefinition, IReadOnlyList(Of DTO.ClientSummary))
  7.  
  8.  
  9.         Private ReadOnly m_readRepository As IClientReadRepository
  10.  
  11.         Public Function Handle(query As Definitions.GetActiveClientsQueryDefinition) As IQueryResponse(Of IReadOnlyList(Of DTO.ClientSummary)) Implements IQueryHandler(Of Definitions.GetActiveClientsQueryDefinition, IReadOnlyList(Of DTO.ClientSummary)).Handle
  12.  
  13.             If (m_readRepository IsNot Nothing) Then
  14.                 Dim dtoConverter As New Converter(Of TaskBazaar.Repository.ClientRecord, DTO.ClientSummary)(AddressOf ConvertToDTO)
  15.                 Return m_readRepository.GetWhere(Function(f As ClientRecord) (f.Active = True)).Values.ToList.ConvertAll(dtoConverter)
  16.             Else
  17.                 Throw New MissingRepositoryException("IClientReadRepository")
  18.             End If
  19.  
  20.         End Function
  21.  
  22.         ''' <summary>
  23.         ''' Create a new handler for the active clients query using the given repository
  24.         ''' </summary>
  25.         ''' <param name="readRepository">
  26.         ''' The read repository to use to retrieve the data
  27.         ''' </param>
  28.         Public Sub New(ByVal readRepository As IClientReadRepository)
  29.             m_readRepository = readRepository
  30.         End Sub
  31.  
  32.     End Class
  33. End Namespace

As you can see it must take an IClientReadRepository in the constructor.

I populate the unity container thus:-

vb.net Code:
  1. Public Shared Sub RegisterTypes(container As IUnityContainer)
  2.  
  3.         Dim interfaceType As Type = Nothing
  4.  
  5.         'Get any repository handlers...we will use the namespace to differentiate between back end technologies
  6.         interfaceType = GetType(IRepositoryRead(Of ,))
  7.  
  8.         container.RegisterTypes(AllClasses.FromAssembliesInBasePath(includeUnityAssemblies:=False, includeSystemAssemblies:=False).Where(Function(z) z.Namespace.Contains("Azure")).Where(Function(t) t.ImplementsInterface(interfaceType)),
  9.              getFromTypes:=Function() WithMappings.FromMatchingInterface(interfaceType),
  10.              getName:=Function(i) WithName.TypeName(i),
  11.              getLifetimeManager:=Function(i) WithLifetime.PerThread(i)
  12.                                 )
  13.  
  14.         'Get the interface definition for the generic query handler interface we are looking for
  15.         interfaceType = GetType(IQueryHandler(Of ,))
  16.  
  17.         container.RegisterTypes(AllClasses.FromAssembliesInBasePath(includeUnityAssemblies:=False, includeSystemAssemblies:=False).Where(Function(t) t.ImplementsInterface(interfaceType)),
  18.               getName:=Function(i) GetNameFromQueryDefinition(i),
  19.               getLifetimeManager:=Function(i) WithLifetime.PerThread(i),
  20.               getInjectionMembers:=Function(i) GetConstructorInjections(i))
  21.  
  22.  
  23.  
  24.     End Sub

But what do I need to put in the GetConstructorInjections so it knows to create the ClientRepository when it creates the GetActiveClientsQueryHandler?

e.g. what goes in :-

vb.net Code:
  1. Private Shared Function GetConstructorInjections(i As Type)
  2.            As IEnumerable(Of InjectionMember)
  3.  
  4.   ' Get the constructor for i that has any
  5.   ' IReadRepository derived parameters
  6.  
  7.  
  8.     End Function