예제 #1
0
        public virtual object AkkaResolve(Type serviceType, object rsn, bool isAForcedActorSearch = false)
        {
            IActorRef actorReference;

            try
            {
                if (AkkaActors.TryGetValue(serviceType, out actorReference))
                {
                    return(actorReference);
                }
                if (!isAForcedActorSearch)
                {
                    return(base.Resolve(serviceType));
                }
            }
            catch (ActivationException) { throw; }
            catch (/*ActorInitialization*/ Exception) { }

            Props properties;
            Type  typeToTest = serviceType;

            while (typeToTest != null)
            {
                Type[] types = typeToTest.GenericTypeArguments;
                if (types.Length == 1)
                {
                    Type aggregateType = typeof(AkkaAggregateRoot <>).MakeGenericType(typeToTest.GenericTypeArguments.Single());
                    if (typeToTest == aggregateType)
                    {
                        typeToTest = aggregateType;
                        break;
                    }
                }
                typeToTest = typeToTest.BaseType;
            }
            if (typeToTest == null || !(typeToTest).IsAssignableFrom(serviceType))
            {
                properties = Props.Create(() => (ActorBase)RootResolve(serviceType));
            }
            else
            {
                properties = Props.Create(() => (ActorBase)AggregateFactory.CreateAggregate(serviceType, rsn as Guid?, false));
            }
            string actorName = serviceType.FullName.Replace("`", string.Empty);
            int    index     = actorName.IndexOf("[[", StringComparison.Ordinal);

            if (index > -1)
            {
                actorName = actorName.Substring(0, index);
            }
            actorReference = AkkaSystem.ActorOf(properties, string.Format("{0}~{1}", actorName, rsn));
            AkkaActors.Add(serviceType, actorReference);
            return(actorReference);
        }
        /// <summary>
        /// Resolves instances of <paramref name="serviceType"/> looking up <see cref="AkkaActors"/>, then <see cref="IDependencyResolver.Resolve{T}"/> and finally <see cref="AggregateFactory"/>.
        /// </summary>
        public virtual object AkkaResolve(Type serviceType, object rsn, bool isAForcedActorSearch = false)
        {
            do
            {
                IActorRef actorReference;
                try
                {
                    if (AkkaActors.TryGetValue(serviceType, out actorReference))
                    {
                        return(actorReference);
                    }
                    if (!isAForcedActorSearch)
                    {
                        return(base.Resolve(serviceType));
                    }
                }
                catch (ActivationException) { throw; }
                catch (/*ActorInitialization*/ Exception) { /* */ }

                Props properties;
                Type  typeToTest = serviceType;
                while (typeToTest != null)
                {
                    Type[] types = typeToTest.GenericTypeArguments;
                    if (types.Length == 1)
                    {
                        Type aggregateType = typeof(AkkaAggregateRoot <>).MakeGenericType(typeToTest.GenericTypeArguments.Single());
                        if (typeToTest == aggregateType)
                        {
                            typeToTest = aggregateType;
                            break;
                        }
                        Type sagaType = typeof(AkkaSaga <>).MakeGenericType(typeToTest.GenericTypeArguments.Single());
                        if (typeToTest == sagaType)
                        {
                            typeToTest = sagaType;
                            break;
                        }
                    }
                    typeToTest = typeToTest.BaseType;
                }

                // This sorts out an out-of-order binder issue
                if (AggregateFactory == null)
                {
                    AggregateFactory = Resolve <IAggregateFactory>();
                }

                if (typeToTest == null || !(typeToTest).IsAssignableFrom(serviceType))
                {
                    properties = Props.Create(() => (ActorBase)RootResolve(serviceType));
                }
                else
                {
                    properties = Props.Create(() => (ActorBase)AggregateFactory.Create(serviceType, rsn as Guid?, false));
                }
                string actorName = serviceType.FullName.Replace("`", string.Empty);
                int    index     = actorName.IndexOf("[[", StringComparison.Ordinal);
                if (index > -1)
                {
                    actorName = actorName.Substring(0, index);
                }
                try
                {
                    actorReference = AkkaSystem.ActorOf(properties, string.Format("{0}~{1}", actorName, rsn));
                }
                catch (InvalidActorNameException)
                {
                    // This means that the actor has been created since we tried to get it... funnily enough concurrency doesn't actually mean concurrency.
                    continue;
                }
                AkkaActors.Add(serviceType, actorReference);
                return(actorReference);
            } while (true);
        }