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:
Imports TaskBazaar.Query Imports TaskBazaar.Repository Namespace Handlers Public Class GetActiveClientsQueryHandler Implements IQueryHandler(Of Definitions.GetActiveClientsQueryDefinition, IReadOnlyList(Of DTO.ClientSummary)) Private ReadOnly m_readRepository As IClientReadRepository Public Function Handle(query As Definitions.GetActiveClientsQueryDefinition) As IQueryResponse(Of IReadOnlyList(Of DTO.ClientSummary)) Implements IQueryHandler(Of Definitions.GetActiveClientsQueryDefinition, IReadOnlyList(Of DTO.ClientSummary)).Handle If (m_readRepository IsNot Nothing) Then Dim dtoConverter As New Converter(Of TaskBazaar.Repository.ClientRecord, DTO.ClientSummary)(AddressOf ConvertToDTO) Return m_readRepository.GetWhere(Function(f As ClientRecord) (f.Active = True)).Values.ToList.ConvertAll(dtoConverter) Else Throw New MissingRepositoryException("IClientReadRepository") End If End Function ''' <summary> ''' Create a new handler for the active clients query using the given repository ''' </summary> ''' <param name="readRepository"> ''' The read repository to use to retrieve the data ''' </param> Public Sub New(ByVal readRepository As IClientReadRepository) m_readRepository = readRepository End Sub End Class End Namespace
As you can see it must take an IClientReadRepository in the constructor.
I populate the unity container thus:-
vb.net Code:
Public Shared Sub RegisterTypes(container As IUnityContainer) Dim interfaceType As Type = Nothing 'Get any repository handlers...we will use the namespace to differentiate between back end technologies interfaceType = GetType(IRepositoryRead(Of ,)) container.RegisterTypes(AllClasses.FromAssembliesInBasePath(includeUnityAssemblies:=False, includeSystemAssemblies:=False).Where(Function(z) z.Namespace.Contains("Azure")).Where(Function(t) t.ImplementsInterface(interfaceType)), getFromTypes:=Function() WithMappings.FromMatchingInterface(interfaceType), getName:=Function(i) WithName.TypeName(i), getLifetimeManager:=Function(i) WithLifetime.PerThread(i) ) 'Get the interface definition for the generic query handler interface we are looking for interfaceType = GetType(IQueryHandler(Of ,)) container.RegisterTypes(AllClasses.FromAssembliesInBasePath(includeUnityAssemblies:=False, includeSystemAssemblies:=False).Where(Function(t) t.ImplementsInterface(interfaceType)), getName:=Function(i) GetNameFromQueryDefinition(i), getLifetimeManager:=Function(i) WithLifetime.PerThread(i), getInjectionMembers:=Function(i) GetConstructorInjections(i)) 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:
Private Shared Function GetConstructorInjections(i As Type) As IEnumerable(Of InjectionMember) ' Get the constructor for i that has any ' IReadRepository derived parameters End Function




Reply With Quote
