1+ using System ;
2+ using System . Collections . Generic ;
3+ using System . Linq ;
4+ using System . Reflection ;
5+ using SimpleInjector ;
6+ using SimpleInjector . Advanced ;
7+ using Xer . Cqrs . CommandStack ;
8+ using Xer . Cqrs . CommandStack . Attributes ;
9+ using Xer . Cqrs . CommandStack . Resolvers ;
10+ using Xer . Cqrs . EventStack ;
11+ using Xer . Cqrs . EventStack . Attributes ;
12+ using Xer . Cqrs . EventStack . Resolvers ;
13+ using Xer . Delegator ;
14+ using Xer . Delegator . Registrations ;
15+ using Xer . Delegator . Resolvers ;
16+
17+ namespace Xer . Cqrs . Extensions . SimpleInjector
18+ {
19+ internal class CqrsBuilder : ICqrsBuilder
20+ {
21+ private readonly Container _container ;
22+
23+ public CqrsBuilder ( Container container )
24+ {
25+ _container = container ;
26+ }
27+
28+ public ICqrsBuilder RegisterCommandDelegator ( )
29+ {
30+ _container . RegisterSingleton < CommandDelegator > ( ( ) =>
31+ {
32+ if ( tryGetInstance ( out IEnumerable < CommandHandlerDelegateResolver > commandHandlerResolvers ) )
33+ {
34+ CommandHandlerDelegateResolver [ ] resolverArray = commandHandlerResolvers . ToArray ( ) ;
35+
36+ if ( resolverArray . Length == 1 )
37+ {
38+ return new CommandDelegator ( resolverArray [ 0 ] ) ;
39+ }
40+
41+ return new CommandDelegator ( CompositeMessageHandlerResolver . Compose ( resolverArray ) ) ;
42+ }
43+
44+ return new CommandDelegator ( new SingleMessageHandlerRegistration ( ) . BuildMessageHandlerResolver ( ) ) ;
45+ } ) ;
46+
47+ return this ;
48+ }
49+
50+ public ICqrsBuilder RegisterCommandHandlers ( Assembly assembly )
51+ {
52+ return RegisterCommandHandlers ( assembly , Lifestyle . Transient ) ;
53+ }
54+
55+ public ICqrsBuilder RegisterCommandHandlers ( Assembly assembly , Lifestyle lifeStyle )
56+ {
57+ return RegisterCommandHandlers ( new [ ] { assembly } , lifeStyle ) ;
58+ }
59+
60+ public ICqrsBuilder RegisterCommandHandlers ( IEnumerable < Assembly > assemblies )
61+ {
62+ return RegisterCommandHandlers ( assemblies , Lifestyle . Transient ) ;
63+ }
64+
65+ public ICqrsBuilder RegisterCommandHandlers ( IEnumerable < Assembly > assemblies , Lifestyle lifeStyle )
66+ {
67+ _container . Register ( typeof ( ICommandAsyncHandler < > ) , assemblies , lifeStyle ) ;
68+ _container . Register ( typeof ( ICommandHandler < > ) , assemblies , lifeStyle ) ;
69+
70+ // Register resolver.
71+ _container . AppendToCollection (
72+ typeof ( CommandHandlerDelegateResolver ) ,
73+ Lifestyle . Singleton . CreateRegistration ( ( ) =>
74+ new CommandHandlerDelegateResolver (
75+ // Combine async and sync command handler resolver.
76+ CompositeMessageHandlerResolver . Compose (
77+ new ContainerCommandAsyncHandlerResolver ( new SimpleInjectorContainerAdapter ( _container ) ) ,
78+ new ContainerCommandHandlerResolver ( new SimpleInjectorContainerAdapter ( _container ) ) ) ) ,
79+ _container
80+ )
81+ ) ;
82+
83+ return this ;
84+ }
85+
86+ public ICqrsBuilder RegisterCommandHandlersAttributes ( Assembly assembly )
87+ {
88+ return RegisterCommandHandlersAttributes ( assembly , Lifestyle . Transient ) ;
89+ }
90+
91+ public ICqrsBuilder RegisterCommandHandlersAttributes ( Assembly assembly , Lifestyle lifeStyle )
92+ {
93+ return RegisterCommandHandlersAttributes ( new [ ] { assembly } , lifeStyle ) ;
94+ }
95+
96+ public ICqrsBuilder RegisterCommandHandlersAttributes ( IEnumerable < Assembly > assemblies )
97+ {
98+ return RegisterCommandHandlersAttributes ( assemblies , Lifestyle . Transient ) ;
99+ }
100+
101+ public ICqrsBuilder RegisterCommandHandlersAttributes ( IEnumerable < Assembly > assemblies , Lifestyle lifeStyle )
102+ {
103+ // Get all types that has methods marked with [CommandHandler] attribute.
104+ IEnumerable < Type > allTypes = assemblies . SelectMany ( assembly => assembly . GetTypes ( ) )
105+ . Where ( type => type . IsClass &&
106+ ! type . IsAbstract &&
107+ CommandHandlerAttributeMethod . IsFoundInType ( type ) ) . ToArray ( ) ;
108+
109+ foreach ( Type type in allTypes )
110+ {
111+ // Register type as self.
112+ _container . Register ( type , type , lifeStyle ) ;
113+ }
114+
115+ var singleMessageHandlerRegistration = new SingleMessageHandlerRegistration ( ) ;
116+ singleMessageHandlerRegistration . RegisterCommandHandlerAttributes ( allTypes , _container . GetInstance ) ;
117+
118+ // Register resolver.
119+ _container . AppendToCollection (
120+ typeof ( CommandHandlerDelegateResolver ) ,
121+ Lifestyle . Singleton . CreateRegistration ( ( ) =>
122+ new CommandHandlerDelegateResolver ( singleMessageHandlerRegistration . BuildMessageHandlerResolver ( ) ) ,
123+ _container
124+ )
125+ ) ;
126+
127+ return this ;
128+ }
129+
130+ public ICqrsBuilder RegisterEventDelegator ( )
131+ {
132+ _container . RegisterSingleton < EventDelegator > ( ( ) =>
133+ {
134+ if ( tryGetInstance ( out IEnumerable < EventHandlerDelegateResolver > eventHandlerResolvers ) )
135+ {
136+ EventHandlerDelegateResolver [ ] resolverArray = eventHandlerResolvers . ToArray ( ) ;
137+
138+ if ( resolverArray . Length == 1 )
139+ {
140+ return new EventDelegator ( resolverArray [ 0 ] ) ;
141+ }
142+
143+ return new EventDelegator ( CompositeMessageHandlerResolver . Compose ( resolverArray ) ) ;
144+ }
145+
146+ return new EventDelegator ( new SingleMessageHandlerRegistration ( ) . BuildMessageHandlerResolver ( ) ) ;
147+ } ) ;
148+
149+ return this ;
150+ }
151+
152+ public ICqrsBuilder RegisterEventHandlers ( Assembly assembly )
153+ {
154+ return RegisterEventHandlers ( assembly , Lifestyle . Transient ) ;
155+ }
156+
157+ public ICqrsBuilder RegisterEventHandlers ( Assembly assembly , Lifestyle lifeStyle )
158+ {
159+ return RegisterEventHandlers ( new [ ] { assembly } , lifeStyle ) ;
160+ }
161+
162+ public ICqrsBuilder RegisterEventHandlers ( IEnumerable < Assembly > assemblies )
163+ {
164+ return RegisterEventHandlers ( assemblies , Lifestyle . Transient ) ;
165+ }
166+
167+ public ICqrsBuilder RegisterEventHandlers ( IEnumerable < Assembly > assemblies , Lifestyle lifeStyle )
168+ {
169+ _container . Register ( typeof ( IEventAsyncHandler < > ) , assemblies , lifeStyle ) ;
170+ _container . Register ( typeof ( IEventHandler < > ) , assemblies , lifeStyle ) ;
171+
172+ // Register resolver.
173+ _container . AppendToCollection (
174+ typeof ( EventHandlerDelegateResolver ) ,
175+ Lifestyle . Singleton . CreateRegistration ( ( ) =>
176+ new EventHandlerDelegateResolver ( new ContainerEventHandlerResolver ( new SimpleInjectorContainerAdapter ( _container ) ) ) ,
177+ _container
178+ )
179+ ) ;
180+
181+ return this ;
182+ }
183+
184+ public ICqrsBuilder RegisterEventHandlersAttributes ( Assembly assembly )
185+ {
186+ return RegisterEventHandlersAttributes ( assembly , Lifestyle . Transient ) ;
187+ }
188+
189+ public ICqrsBuilder RegisterEventHandlersAttributes ( Assembly assembly , Lifestyle lifeStyle )
190+ {
191+ return RegisterEventHandlersAttributes ( new [ ] { assembly } , lifeStyle ) ;
192+ }
193+
194+ public ICqrsBuilder RegisterEventHandlersAttributes ( IEnumerable < Assembly > assemblies )
195+ {
196+ return RegisterEventHandlersAttributes ( assemblies , Lifestyle . Transient ) ;
197+ }
198+
199+ public ICqrsBuilder RegisterEventHandlersAttributes ( IEnumerable < Assembly > assemblies , Lifestyle lifeStyle )
200+ {
201+ // Get all types that has methods marked with [CommandHandler] attribute.
202+ IEnumerable < Type > allTypes = assemblies . SelectMany ( assembly => assembly . GetTypes ( ) )
203+ . Where ( type => type . IsClass &&
204+ ! type . IsAbstract &&
205+ EventHandlerAttributeMethod . IsFoundInType ( type ) ) . ToArray ( ) ;
206+
207+ foreach ( Type type in allTypes )
208+ {
209+ // Register type as self.
210+ _container . Register ( type , type , lifeStyle ) ;
211+ }
212+
213+ var multiMessageHandlerRegistration = new MultiMessageHandlerRegistration ( ) ;
214+ multiMessageHandlerRegistration . RegisterEventHandlerAttributes ( allTypes , _container . GetInstance ) ;
215+
216+ // Register resolver.
217+ _container . AppendToCollection (
218+ typeof ( EventHandlerDelegateResolver ) ,
219+ Lifestyle . Singleton . CreateRegistration ( ( ) =>
220+ new EventHandlerDelegateResolver ( multiMessageHandlerRegistration . BuildMessageHandlerResolver ( ) ) ,
221+ _container
222+ )
223+ ) ;
224+
225+ return this ;
226+ }
227+
228+ private bool tryGetInstance < T > ( out T instance ) where T : class
229+ {
230+ // Cast to IServiceProvider so that container will not throw if no resolver collection was registered.
231+ IServiceProvider serviceProvider = _container ;
232+
233+ instance = serviceProvider . GetService ( typeof ( T ) ) as T ;
234+ if ( instance == null )
235+ {
236+ return false ;
237+ }
238+
239+ return true ;
240+ }
241+ }
242+ }
0 commit comments