Use UnityConfiguration to automatically wire up constructors?
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
Re: Use UnityConfiguration to automatically wire up constructors?
You shouldn't need to do anything. Unity will attempt automatic constructor injection. Does Unity know about your IClientReadRepository implementation?
Re: Use UnityConfiguration to automatically wire up constructors?
It does, yes - the first set of registrations includes it:
vb.net Code:
'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)
)
But in fact my IClientReadRepository itself inherits IRepositoryRead(Of Client, Integer)).. maybe this extra step is befuddling it.