Click here to Skip to main content
15,881,803 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
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
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
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
Private Shared Function GetConstructorInjections(i As Type)
       As IEnumerable(Of InjectionMember)

    ' Get the constructor for i that has any IReadRepository derived parameters


End Function
Posted

1 solution

It does work if I explicitly wire up the registrations:-

VB
container.RegisterType(GetType(ITaskReadRepository), GetType(Azure.TaskReadRepository))
container.RegisterType(GetType(IClientReadRepository), GetType(Azure.ClientReadRepository))
container.RegisterType(GetType(IBazaarReadRepository), GetType(Azure.BazaarReadRepository))


So I guess I need to keep plugging away at the auto-registration until I get the same effect.
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900