Line data Source code
1 : #region Copyright
2 : // // -----------------------------------------------------------------------
3 : // // <copyright company="cdmdotnet Limited">
4 : // // Copyright cdmdotnet Limited. All rights reserved.
5 : // // </copyright>
6 : // // -----------------------------------------------------------------------
7 : #endregion
8 :
9 : using System;
10 : using System.Collections.Generic;
11 : using System.Linq;
12 : using System.Reflection;
13 : using Akka.Actor;
14 : using cdmdotnet.Logging;
15 : using Cqrs.Akka.Events;
16 : using Cqrs.Bus;
17 : using Cqrs.Commands;
18 : using Cqrs.Configuration;
19 : using Cqrs.Events;
20 :
21 : namespace Cqrs.Akka.Configuration
22 : {
23 : /// <summary>
24 : /// Triggers the <see cref="BusRegistrar"/> instantiates instances of <see cref="IEventHandler{TAuthenticationToken, TEvent}"/> and <see cref="ICommandHandler{TAuthenticationToken,TCommand}"/> classes that inherit the akka.net <see cref="ReceiveActor"/> via the <see cref="IDependencyResolver"/> so their message registration kicks in.
25 : /// </summary>
26 : public class AkkaBusRegistrar<TAuthenticationToken> : BusRegistrar
27 1 : {
28 : protected IHandlerResolver HandlerResolver { get; private set; }
29 :
30 0 : public AkkaBusRegistrar(IDependencyResolver dependencyResolver, IHandlerResolver handlerResolver)
31 : : base(dependencyResolver)
32 : {
33 : HandlerResolver = handlerResolver;
34 : }
35 :
36 : #region Overrides of BusRegistrar
37 :
38 0 : protected override HandlerDelegate BuildDelegateAction(Type executorType, Func<Type, IEnumerable<Type>> resolveMessageHandlerInterface)
39 : {
40 : Type targetedType = executorType;
41 : Type @interface = resolveMessageHandlerInterface(executorType).FirstOrDefault();
42 : if (@interface != null && @interface.GenericTypeArguments.Length > 2)
43 : targetedType = executorType.GenericTypeArguments[1];
44 :
45 : Action<dynamic> handlerDelegate = x =>
46 : {
47 : dynamic handler;
48 : try
49 : {
50 : Type messageType = ((object)x).GetType();
51 : object rsn = messageType.GetProperty("Rsn").GetValue(x, null);
52 : handler = HandlerResolver.Resolve(executorType, rsn);
53 : }
54 : catch (Exception)
55 : {
56 : handler = DependencyResolver.Resolve(executorType);
57 : }
58 : IActorRef actorReference = handler as IActorRef;
59 : try
60 : {
61 : if (actorReference != null)
62 : actorReference.Tell((object)x);
63 : else
64 : handler.Handle(x);
65 : }
66 : catch (NotImplementedException exception)
67 : {
68 : var logger = DependencyResolver.Resolve<ILogger>();
69 : logger.LogInfo(string.Format("An event message arrived of the type '{0}' went to a handler of type '{1}' but was not implemented.", x.GetType().FullName, handler.GetType().FullName), exception: exception);
70 : }
71 : };
72 :
73 : // Instantiate an instance so it triggers the constructor with it's registrations
74 : DependencyResolver.Resolve(executorType);
75 :
76 : return new HandlerDelegate { Delegate = handlerDelegate, TargetedType = targetedType };
77 : }
78 :
79 0 : protected override void InvokeHandlerDelegate(MethodInfo registerExecutorMethod, bool trueForEventsFalseForCommands, HandlerDelegate handlerDelegate)
80 : {
81 : base.InvokeHandlerDelegate(registerExecutorMethod, trueForEventsFalseForCommands, handlerDelegate);
82 : registerExecutorMethod.Invoke(DependencyResolver.Resolve<IAkkaEventPublisher<TAuthenticationToken>>(), new object[] { handlerDelegate.Delegate, handlerDelegate.TargetedType });
83 : }
84 :
85 : #endregion
86 : }
87 : }
|