LCOV - code coverage report
Current view: top level - Ninject/Cqrs.Ninject.Akka - AkkaNinjectDependencyResolver.cs Hit Total Coverage
Test: doc-coverage.info Lines: 2 12 16.7 %
Date: 2017-07-26

          Line data    Source code
       1             : using System;
       2             : using System.Collections.Concurrent;
       3             : using System.Collections.Generic;
       4             : using System.Linq;
       5             : using Akka.Actor;
       6             : using Cqrs.Akka.Configuration;
       7             : using Cqrs.Akka.Domain;
       8             : using Cqrs.Domain;
       9             : using Cqrs.Domain.Factories;
      10             : using Cqrs.Ninject.Configuration;
      11             : using Ninject;
      12             : 
      13             : namespace Cqrs.Ninject.Akka
      14             : {
      15             :         public class AkkaNinjectDependencyResolver
      16             :                 : NinjectDependencyResolver
      17             :                 , IAkkaAggregateResolver
      18             :                 , IAkkaSagaResolver
      19             :                 , IHandlerResolver
      20           0 :         {
      21             :                 protected global::Akka.DI.Ninject.NinjectDependencyResolver RawAkkaNinjectDependencyResolver { get; set; }
      22             : 
      23             :                 protected ActorSystem AkkaSystem { get; private set; }
      24             : 
      25             :                 protected IDictionary<Type, IActorRef> AkkaActors { get; private set; }
      26             : 
      27             :                 protected IAggregateFactory AggregateFactory { get; private set; }
      28             : 
      29           0 :                 public AkkaNinjectDependencyResolver(IKernel kernel, ActorSystem system)
      30             :                         : base(kernel)
      31             :                 {
      32             :                         RawAkkaNinjectDependencyResolver = new global::Akka.DI.Ninject.NinjectDependencyResolver(kernel, AkkaSystem = system);
      33             :                         AkkaActors = new ConcurrentDictionary<Type, IActorRef>();
      34             :                         AggregateFactory = Resolve<IAggregateFactory>();
      35             :                 }
      36             : 
      37           0 :                 protected override void BindDependencyResolver()
      38             :                 {
      39             :                         bool isDependencyResolverBound = Kernel.GetBindings(typeof(Cqrs.Configuration.IDependencyResolver)).Any();
      40             :                         if (isDependencyResolverBound)
      41             :                                 Kernel.Unbind<Cqrs.Configuration.IDependencyResolver>();
      42             :                         Kernel.Bind<Cqrs.Configuration.IDependencyResolver>()
      43             :                                 .ToConstant(this)
      44             :                                 .InSingletonScope();
      45             : 
      46             :                         isDependencyResolverBound = Kernel.GetBindings(typeof(IAkkaAggregateResolver)).Any();
      47             :                         if (!isDependencyResolverBound)
      48             :                         {
      49             :                                 Kernel.Bind<IAkkaAggregateResolver>()
      50             :                                         .ToConstant(this)
      51             :                                         .InSingletonScope();
      52             :                         }
      53             :                 }
      54             : 
      55             :                 /// <summary>
      56             :                 /// Starts the <see cref="AkkaNinjectDependencyResolver"/>
      57             :                 /// </summary>
      58             :                 /// <remarks>
      59             :                 /// this exists to the static constructor can be triggered.
      60             :                 /// </remarks>
      61           1 :                 public new static void Start(IKernel kernel = null, bool prepareProvidedKernel = false)
      62             :                 {
      63             :                         // Create the ActorSystem and Dependency Resolver
      64             :                         ActorSystem system = ActorSystem.Create("Cqrs");
      65             : 
      66             :                         Func<IKernel, NinjectDependencyResolver> originalDependencyResolverCreator = DependencyResolverCreator;
      67             :                         Func<IKernel, NinjectDependencyResolver> dependencyResolverCreator = container => new AkkaNinjectDependencyResolver(container, system);
      68             :                         if (originalDependencyResolverCreator == null)
      69             :                                 DependencyResolverCreator = dependencyResolverCreator;
      70             :                         else
      71             :                                 DependencyResolverCreator = container =>
      72             :                                 {
      73             :                                         originalDependencyResolverCreator(container);
      74             :                                         return dependencyResolverCreator(container);
      75             :                                 };
      76             : 
      77             :                         NinjectDependencyResolver.Start(kernel, prepareProvidedKernel);
      78             :                 }
      79             : 
      80           0 :                 public static void Stop()
      81             :                 {
      82             :                         var di = Current as AkkaNinjectDependencyResolver;
      83             :                         if (di != null)
      84             :                                 di.AkkaSystem.Shutdown();
      85             :                 }
      86             : 
      87             :                 #region Overrides of NinjectDependencyResolver
      88             : 
      89           1 :                 public override object Resolve(Type serviceType)
      90             :                 {
      91             :                         return Resolve(serviceType, null);
      92             :                 }
      93             : 
      94             :                 #endregion
      95             : 
      96             :                 #region Implementation of IAkkaAggregateResolver
      97             : 
      98           0 :                 public virtual IActorRef ResolveActor<TAggregate, TAuthenticationToken>(Guid rsn)
      99             :                         where TAggregate : IAggregateRoot<TAuthenticationToken>
     100             :                 {
     101             :                         return (IActorRef)AkkaResolve(typeof(TAggregate), rsn, true);
     102             :                 }
     103             : 
     104           0 :                 public IActorRef ResolveActor<T>()
     105             :                 {
     106             :                         return (IActorRef)AkkaResolve(typeof(T), null, true);
     107             :                 }
     108             : 
     109             :                 #endregion
     110             : 
     111             :                 #region Implementation of IAkkaSagaResolver
     112             : 
     113             :                 IActorRef IAkkaSagaResolver.ResolveActor<TSaga, TAuthenticationToken>(Guid rsn)
     114             :                 {
     115             :                         return ResolveSagaActor<TSaga, TAuthenticationToken>(rsn);
     116             :                 }
     117             : 
     118           0 :                 public virtual IActorRef ResolveSagaActor<TSaga, TAuthenticationToken>(Guid rsn)
     119             :                         where TSaga : ISaga<TAuthenticationToken>
     120             :                 {
     121             :                         return (IActorRef)AkkaResolve(typeof(TSaga), rsn, true);
     122             :                 }
     123             : 
     124             :                 #endregion
     125             : 
     126           0 :                 protected virtual object RootResolve(Type serviceType)
     127             :                 {
     128             :                         return base.Resolve(serviceType);
     129             :                 }
     130             : 
     131           0 :                 public virtual object Resolve(Type serviceType, object rsn)
     132             :                 {
     133             :                         return AkkaResolve(serviceType, rsn);
     134             :                 }
     135             : 
     136           0 :                 public virtual object AkkaResolve(Type serviceType, object rsn, bool isAForcedActorSearch = false)
     137             :                 {
     138             :                         IActorRef actorReference;
     139             :                         try
     140             :                         {
     141             :                                 if (AkkaActors.TryGetValue(serviceType, out actorReference))
     142             :                                         return actorReference;
     143             :                                 if (!isAForcedActorSearch)
     144             :                                         return base.Resolve(serviceType);
     145             :                         }
     146             :                         catch (ActivationException) { throw; }
     147             :                         catch ( /*ActorInitialization*/Exception) { }
     148             : 
     149             :                         Props properties;
     150             :                         Type typeToTest = serviceType;
     151             :                         while (typeToTest != null)
     152             :                         {
     153             :                                 Type[] types = typeToTest.GenericTypeArguments;
     154             :                                 if (types.Length == 1)
     155             :                                 {
     156             :                                         Type aggregateType = typeof (AkkaAggregateRoot<>).MakeGenericType(typeToTest.GenericTypeArguments.Single());
     157             :                                         if (typeToTest == aggregateType)
     158             :                                         {
     159             :                                                 typeToTest = aggregateType;
     160             :                                                 break;
     161             :                                         }
     162             :                                         Type sagaType = typeof (AkkaSaga<>).MakeGenericType(typeToTest.GenericTypeArguments.Single());
     163             :                                         if (typeToTest == sagaType)
     164             :                                         {
     165             :                                                 typeToTest = sagaType;
     166             :                                                 break;
     167             :                                         }
     168             :                                 }
     169             :                                 typeToTest = typeToTest.BaseType;
     170             :                         }
     171             : 
     172             :                         // This sorts out an out-of-order binder issue
     173             :                         if (AggregateFactory == null)
     174             :                                 AggregateFactory = Resolve<IAggregateFactory>();
     175             : 
     176             :                         if (typeToTest == null || !(typeToTest).IsAssignableFrom(serviceType))
     177             :                                 properties = Props.Create(() => (ActorBase)RootResolve(serviceType));
     178             :                         else
     179             :                                 properties = Props.Create(() => (ActorBase) AggregateFactory.Create(serviceType, rsn as Guid?, false));
     180             :                         string actorName = serviceType.FullName.Replace("`", string.Empty);
     181             :                         int index = actorName.IndexOf("[[", StringComparison.Ordinal);
     182             :                         if (index > -1)
     183             :                                 actorName = actorName.Substring(0, index);
     184             :                         actorReference = AkkaSystem.ActorOf(properties, string.Format("{0}~{1}", actorName, rsn));
     185             :                         AkkaActors.Add(serviceType, actorReference);
     186             :                         return actorReference;
     187             :                 }
     188             :         }
     189             : }

Generated by: LCOV version 1.10