Exemplo n.º 1
0
 private String ShallowArgString(InjectionPlan arg)
 {
     if (arg is Constructor || arg is Subplan)
     {
         return(arg.GetType().Name + ": " + arg.GetNode().GetName());
     }
     else
     {
         return(arg.ToShallowString());
     }
 }
Exemplo n.º 2
0
        private object GetInstance(INode node)
        {
            InjectionPlan plan = (InjectionPlan)GetInjectionPlan(node);
            object        u    = InjectFromPlan(plan);

            while (pendingFutures.Count != 0)
            {
                IEnumerator <object> i = pendingFutures.GetEnumerator();
                i.MoveNext();
                IInjectionFuture <object> f = (IInjectionFuture <object>)i.Current;
                pendingFutures.Remove(f);
                f.Get();
            }
            return(u);
        }
Exemplo n.º 3
0
 private InjectionPlan BuildClassNodeInjectionPlan(IClassNode cn,
                                                   object cachedInstance,
                                                   IClassNode externalConstructor,
                                                   IClassNode boundImpl,
                                                   IClassNode defaultImpl,
                                                   IDictionary <INode, InjectionPlan> memo)
 {
     if (cachedInstance != null)
     {
         return(new CsInstance(cn, cachedInstance));
     }
     else if (externalConstructor != null)
     {
         BuildInjectionPlan(externalConstructor, memo);
         InjectionPlan ip = null;
         memo.TryGetValue(externalConstructor, out ip);
         return(new Subplan(cn, 0, new InjectionPlan[] { ip }));
     }
     else if (boundImpl != null && !cn.Equals(boundImpl))
     {
         // We need to delegate to boundImpl, so recurse.
         BuildInjectionPlan(boundImpl, memo);
         InjectionPlan ip = null;
         memo.TryGetValue(boundImpl, out ip);
         return(new Subplan(cn, 0, new InjectionPlan[] { ip }));
     }
     else if (defaultImpl != null && !cn.Equals(defaultImpl))
     {
         BuildInjectionPlan(defaultImpl, memo);
         InjectionPlan ip = null;
         memo.TryGetValue(defaultImpl, out ip);
         return(new Subplan(cn, 0, new InjectionPlan[] { ip }));
     }
     else
     {
         // if we're here and there is a bound impl or a default impl,
         // then we're bound / defaulted to ourselves, so don't add
         // other impls to the list of things to consider.
         List <IClassNode> candidateImplementations = new List <IClassNode>();
         candidateImplementations.Add(cn);
         List <InjectionPlan> sub_ips = FilterCandidateConstructors(candidateImplementations, memo);
         if (sub_ips.Count == 1)
         {
             return(WrapInjectionPlans(cn, sub_ips, false, -1));
         }
         return(WrapInjectionPlans(cn, sub_ips, true, -1));
     }
 }
Exemplo n.º 4
0
        public InjectionPlan GetInjectionPlan(INode n)
        {
            AssertNotConcurrent();
            IDictionary <INode, InjectionPlan> memo = new Dictionary <INode, InjectionPlan>();

            BuildInjectionPlan(n, memo);

            InjectionPlan p = null;

            memo.TryGetValue(n, out p);

            if (p != null)
            {
                return(p);
            }
            Org.Apache.Reef.Utilities.Diagnostics.Exceptions.Throw(new InjectionException("Fail to get injection plan" + n), LOGGER);
            return(null);//this line shouild be not reached as Throw throws exception
        }
Exemplo n.º 5
0
 private void CreateInjectionPlanForCollectionElements <T>(INode n, IDictionary <INode, InjectionPlan> memo, ICollection <T> entries, ICollection <InjectionPlan> plans)
 {
     foreach (var entry in entries)
     {
         if (entry is IClassNode)
         {
             BuildInjectionPlan((IClassNode)entry, memo);
             InjectionPlan p2 = null;
             memo.TryGetValue((INode)entry, out p2);
             if (p2 != null)
             {
                 plans.Add(p2);
             }
         }
         else
         {
             plans.Add(new CsInstance(n, entry));
         }
     }
 }
Exemplo n.º 6
0
 public InjectionPlan[] GetPlans()
 {
     InjectionPlan[] copy = new InjectionPlan[alternatives.Length];
     Array.Copy(alternatives, copy, alternatives.Length); // not sure if it does deep copy??
     return(copy);
 }
Exemplo n.º 7
0
        public bool IsParameterSet(string name)
        {
            InjectionPlan p = GetInjectionPlan(classHierarchy.GetNode(name));

            return(p.IsInjectable());
        }
Exemplo n.º 8
0
        public object InjectFromPlan(InjectionPlan plan)
        {
            if (!plan.IsFeasible())
            {
                var ex = new InjectionException("Cannot inject " + plan.GetNode().GetFullName() + ": "
                                                + plan.ToCantInjectString());
                Org.Apache.Reef.Utilities.Diagnostics.Exceptions.Throw(ex, LOGGER);
            }

            if (plan.IsAmbiguous())
            {
                var ex = new InjectionException("Cannot inject " + plan.GetNode().GetFullName() + " "
                                                + plan.ToCantInjectString());
                Org.Apache.Reef.Utilities.Diagnostics.Exceptions.Throw(ex, LOGGER);
            }

            if (plan is InjectionFuturePlan)
            {
                InjectionFuturePlan fut = (InjectionFuturePlan)plan;
                INode  node             = fut.GetNode();
                string key = node.GetFullName();
                try
                {
                    Type t        = null;
                    Type nodeType = classHierarchy.ClassForName(node.GetFullName());

                    if (node is IClassNode)
                    {
                        t = nodeType;
                    }
                    else if (node is INamedParameterNode)
                    {
                        var nn = (INamedParameterNode)node;
                        t = classHierarchy.ClassForName(nn.GetFullArgName());
                        if (nn.IsSet())
                        {
                            t = typeof(ISet <>).MakeGenericType(new Type[] { t });
                        }
                    }
                    else
                    {
                        var ex = new ApplicationException("Unexpected node type. Wanted ClassNode or NamedParameterNode.  Got: " + node);
                        Org.Apache.Reef.Utilities.Diagnostics.Exceptions.Throw(ex, LOGGER);
                    }

                    //Java - InjectionFuture<?> ret = new InjectionFuture<>(this, javaNamespace.classForName(fut.getNode().getFullName()));
                    //C# - InjectionFuture<object> ret = new InjectionFutureImpl<object>(this, classHierarchy.ClassForName(fut.GetNode().GetFullName()));
                    //We cannot simply create an object from generic with object as <T>
                    //typeof(InjectionFutureImpl<>).MakeGenericType(t) will get the InjectionFutureImpl generic Type with <T> as t
                    //for ClassNode, t is the Type of the class, for NamedParamterNode, t is the Type of the argument
                    //we then use reflection to invoke the constructor
                    //To retain generic argument information??
                    Type injectionFuture          = typeof(InjectionFutureImpl <>).MakeGenericType(t);
                    var  constructor              = injectionFuture.GetConstructor(new Type[] { typeof(IInjector), typeof(Type) });
                    IInjectionFuture <object> ret = (IInjectionFuture <object>)constructor.Invoke(new object[] { this, nodeType });

                    pendingFutures.Add(ret);
                    return(ret);
                }
                catch (TypeLoadException e)
                {
                    Org.Apache.Reef.Utilities.Diagnostics.Exceptions.Caught(e, Level.Error, LOGGER);
                    Org.Apache.Reef.Utilities.Diagnostics.Exceptions.Throw(new InjectionException("Could not get class for " + key), LOGGER);
                }
            }
            else if (plan.GetNode() is IClassNode && null != GetCachedInstance((IClassNode)plan.GetNode()))
            {
                return(GetCachedInstance((IClassNode)plan.GetNode()));
            }
            else if (plan is CsInstance)
            {
                // TODO: Must be named parameter node.  Check.
                //      throw new IllegalStateException("Instance from plan not in Injector's set of instances?!?");
                return(((CsInstance)plan).instance);
            }
            else if (plan is Constructor)
            {
                Constructor     constructor = (Constructor)plan;
                object[]        args        = new object[constructor.GetArgs().Length];
                InjectionPlan[] argPlans    = constructor.GetArgs();

                for (int i = 0; i < argPlans.Length; i++)
                {
                    args[i] = InjectFromPlan(argPlans[i]);
                }

                try
                {
                    concurrentModificationGuard = true;
                    object ret = null;
                    try
                    {
                        IConstructorDef def = (IConstructorDef)constructor.GetConstructorDef();
                        ConstructorInfo c   = GetConstructor(def);

                        if (aspect != null)
                        {
                            ret = aspect.Inject(def, c, args);
                        }
                        else
                        {
                            ret = c.Invoke(args);
                        }
                    }
                    catch (ArgumentException e)
                    {
                        Org.Apache.Reef.Utilities.Diagnostics.Exceptions.Caught(e, Level.Error, LOGGER);
                        StringBuilder sb = new StringBuilder("Internal Tang error?  Could not call constructor " + constructor.GetConstructorDef() + " with arguments [");
                        foreach (Object o in args)
                        {
                            sb.Append("\n\t" + o);
                        }
                        sb.Append("]");
                        Org.Apache.Reef.Utilities.Diagnostics.Exceptions.Throw(new IllegalStateException(sb.ToString(), e), LOGGER);
                    }
                    if (ret is IExternalConstructor <object> )
                    {
                        ret = ((IExternalConstructor <object>)ret).NewInstance();
                    }
                    instances.Add(constructor.GetNode(), ret);
                    return(ret);
                }
                catch (TargetInvocationException e)
                {
                    Org.Apache.Reef.Utilities.Diagnostics.Exceptions.Caught(e, Level.Error, LOGGER);
                    Org.Apache.Reef.Utilities.Diagnostics.Exceptions.Throw(new InjectionException("Could not invoke constructor: " + plan, e), LOGGER);
                }
                finally
                {
                    concurrentModificationGuard = false;
                }
            }
            else if (plan is Subplan)
            {
                Subplan ambiguous = (Subplan)plan;
                return(InjectFromPlan(ambiguous.GetDelegatedPlan()));
            }
            else if (plan is SetInjectionPlan)
            {
                SetInjectionPlan setPlan   = (SetInjectionPlan)plan;
                INode            n         = setPlan.GetNode();
                string           typeOfSet = null;

                // TODO: This doesn't work for sets of generics (e.g., Set<Foo<int>>
                // because GetFullName and GetFullArgName strip generic info).
                if (n is INamedParameterNode)
                {
                    INamedParameterNode np = (INamedParameterNode)n;
                    typeOfSet = np.GetFullArgName();
                }
                else if (n is IClassNode)
                {
                    typeOfSet = n.GetFullName();
                }
                else
                {
                    Org.Apache.Reef.Utilities.Diagnostics.Exceptions.Throw(new ApplicationException("Unknown node type :" + n.ToString()), LOGGER);
                }

                Type t = classHierarchy.ClassForName(typeOfSet);
                // MakeGenericType(t = int: MonotonicHashSet<> -> MonotonicHashSet<int>
                // Get constructor: MonotonicHashSet<int> -> public MonotonicHashSet<int>() { ... }
                // Invoke: public MonotonicHashSet<int> -> new MonotonicHashSet<int>()

                object ret = typeof(MonotonicHashSet <>).MakeGenericType(t).GetConstructor(new Type[] { }).Invoke(new object[] { }); //(this, classHierarchy.ClassForName(fut.GetNode().GetFullName()));

                MethodInfo mf = ret.GetType().GetMethod("Add");

                foreach (InjectionPlan subplan in setPlan.GetEntryPlans())
                {
//                    ret.Add(InjectFromPlan(subplan));
                    mf.Invoke(ret, new object[] { InjectFromPlan(subplan) });
                }
                return(ret);
            }
            else if (plan is ListInjectionPlan)
            {
                ListInjectionPlan listPlan   = (ListInjectionPlan)plan;
                INode             n          = listPlan.GetNode();
                string            typeOfList = null;

                if (n is INamedParameterNode)
                {
                    INamedParameterNode np = (INamedParameterNode)n;
                    typeOfList = np.GetFullArgName();
                }
                else if (n is IClassNode)
                {
                    typeOfList = n.GetFullName();
                }
                else
                {
                    Org.Apache.Reef.Utilities.Diagnostics.Exceptions.Throw(new ApplicationException("Unknown node type :" + n.ToString()), LOGGER);
                }

                Type   t   = classHierarchy.ClassForName(typeOfList);
                object ret = typeof(List <>).MakeGenericType(t).GetConstructor(new Type[] { }).Invoke(new object[] { });

                MethodInfo mf = ret.GetType().GetMethod("Add");

                foreach (InjectionPlan subplan in listPlan.GetEntryPlans())
                {
                    mf.Invoke(ret, new object[] { InjectFromPlan(subplan) });
                }
                return(ret);
            }
            else
            {
                Org.Apache.Reef.Utilities.Diagnostics.Exceptions.Throw(new IllegalStateException("Unknown plan type: " + plan), LOGGER);
            }
            return(null); // should never reach here
        }
Exemplo n.º 9
0
        private List <InjectionPlan> FilterCandidateConstructors(
            List <IClassNode> candidateImplementations,
            IDictionary <INode, InjectionPlan> memo)
        {
            List <InjectionPlan> sub_ips = new List <InjectionPlan>();

            #region each implementation
            foreach (IClassNode thisCN in candidateImplementations)
            {
                List <InjectionPlan>   constructors    = new List <InjectionPlan>();
                List <IConstructorDef> constructorList = new List <IConstructorDef>();
                if (null != this.configuration.GetLegacyConstructor(thisCN))
                {
                    constructorList.Add(this.configuration.GetLegacyConstructor(thisCN));
                }

                foreach (var c in thisCN.GetInjectableConstructors())
                {
                    constructorList.Add(c);
                }

                #region each constructor
                foreach (IConstructorDef def in constructorList)
                {
                    List <InjectionPlan> args    = new List <InjectionPlan>();
                    IConstructorArg[]    defArgs = def.GetArgs().ToArray <IConstructorArg>();

                    #region each argument
                    foreach (IConstructorArg arg in defArgs)
                    {
                        if (!arg.IsInjectionFuture())
                        {
                            try
                            {
                                INode argNode = this.classHierarchy.GetNode(arg.GetName());
                                BuildInjectionPlan(argNode, memo);
                                InjectionPlan ip = null;
                                memo.TryGetValue(argNode, out ip);
                                args.Add(ip);
                            }
                            catch (NameResolutionException e)
                            {
                                Org.Apache.Reef.Utilities.Diagnostics.Exceptions.Caught(e, Level.Error, LOGGER);

                                var ex = new IllegalStateException("Detected unresolvable "
                                                                   + "constructor arg while building injection plan.  "
                                                                   + "This should have been caught earlier!", e);
                                Org.Apache.Reef.Utilities.Diagnostics.Exceptions.Throw(ex, LOGGER);
                            }
                        }
                        else
                        {
                            try
                            {
                                args.Add(new InjectionFuturePlan(this.classHierarchy.GetNode(arg.GetName())));
                            }
                            catch (NameResolutionException e)
                            {
                                Org.Apache.Reef.Utilities.Diagnostics.Exceptions.Caught(e, Level.Error, LOGGER);
                                var ex = new IllegalStateException("Detected unresolvable "
                                                                   + "constructor arg while building injection plan.  "
                                                                   + "This should have been caught earlier!", e);
                                Org.Apache.Reef.Utilities.Diagnostics.Exceptions.Throw(ex, LOGGER);
                            }
                        }
                    }
                    #endregion each argument

                    Constructor constructor = new Constructor(thisCN, def, args.ToArray());
                    constructors.Add(constructor);
                }
                #endregion each constructor

                // The constructors are embedded in a lattice defined by
                // isMoreSpecificThan().  We want to see if, amongst the injectable
                // plans, there is a unique dominant plan, and select it.
                // First, compute the set of injectable plans.
                List <Int32> liveIndices = new List <Int32>();
                for (int i = 0; i < constructors.Count; i++)
                {
                    if (constructors[i].GetNumAlternatives() > 0)
                    {
                        liveIndices.Add(i);
                    }
                }
                // Now, do an all-by-all comparison, removing indices that are dominated
                // by others.
                int k = -1;
                for (int i = 0; i < liveIndices.Count; i++)
                {
                    for (int j = i + 1; j < liveIndices.Count; j++)
                    {
                        IConstructorDef ci = ((Constructor)constructors[(liveIndices[i])]).GetConstructorDef();
                        IConstructorDef cj = ((Constructor)constructors[(liveIndices[j])]).GetConstructorDef();

                        if (ci.IsMoreSpecificThan(cj)) //ci's arguments is a superset of cj's
                        {
                            k = i;
                        }
                        else if (cj.IsMoreSpecificThan(ci))
                        {
                            k = j;
                        }
                    }
                }
                if (liveIndices.Count == 1)
                {
                    k = 0;
                }
                if (constructors.Count > 0)
                {
                    sub_ips.Add(WrapInjectionPlans(thisCN, constructors, false, k != -1 ? liveIndices[k] : -1));
                }
            }
            #endregion each implementation
            return(sub_ips);
        }
Exemplo n.º 10
0
        private void BuildInjectionPlan(INode n, IDictionary <INode, InjectionPlan> memo)
        {
            if (memo.ContainsKey(n))
            {
                InjectionPlan p = null;
                memo.TryGetValue(n, out p);
                if (BUILDING == p)
                {
                    StringBuilder loopyList = new StringBuilder("[");
                    foreach (INode node in memo.Keys)
                    {
                        InjectionPlan p1 = null;
                        memo.TryGetValue(node, out p1);
                        if (p1 == BUILDING)
                        {
                            loopyList.Append(" " + node.GetFullName());
                        }
                    }
                    loopyList.Append(" ]");
                    var ex = new ClassHierarchyException("Detected loopy constructor involving "
                                                         + loopyList.ToString());
                    Org.Apache.Reef.Utilities.Diagnostics.Exceptions.Throw(ex, LOGGER);
                }
                else
                {
                    return;
                }
            }
            memo.Add(n, BUILDING);
            InjectionPlan ip = null;

            if (n is INamedParameterNode)
            {
                INamedParameterNode np = (INamedParameterNode)n;
                object boundInstance   = ParseBoundNamedParameter(np);
                object defaultInstance = this.classHierarchy.ParseDefaultValue(np);
                object instance        = boundInstance != null ? boundInstance : defaultInstance;

                if (instance is INode)
                {
                    BuildInjectionPlan((INode)instance, memo);
                    InjectionPlan sp;
                    memo.TryGetValue((INode)instance, out sp);
                    ip = new Subplan(n, 0, new InjectionPlan[] { sp });
                }
                else if (instance is ISet <object> )
                {
                    ISet <object> entries = (ISet <object>)instance;
                    ip = CreateSetInjectionPlan(n, memo, entries);
                }
                else if (instance is ISet <INode> )
                {
                    ISet <INode> entries = (ISet <INode>)instance;
                    ip = CreateSetInjectionPlan(n, memo, entries);
                }
                else if (instance is IList <object> )
                {
                    IList <object> entries = (IList <object>)instance;
                    ip = CreateListInjectionPlan(n, memo, entries);
                }
                else if (instance is IList <INode> )
                {
                    IList <INode> entries = (IList <INode>)instance;
                    ip = CreateListInjectionPlan(n, memo, entries);
                }
                else
                {
                    ip = new CsInstance(np, instance);
                }
            }
            else if (n is IClassNode)
            {
                IClassNode cn = (IClassNode)n;

                // Any (or all) of the next four values might be null; that's fine.
                object     cached      = GetCachedInstance(cn);
                IClassNode boundImpl   = this.configuration.GetBoundImplementation(cn);
                IClassNode defaultImpl = ParseDefaultImplementation(cn);
                IClassNode ec          = this.configuration.GetBoundConstructor(cn);

                ip = BuildClassNodeInjectionPlan(cn, cached, ec, boundImpl, defaultImpl, memo);
            }
            else if (n is IPackageNode)
            {
                Org.Apache.Reef.Utilities.Diagnostics.Exceptions.Throw(new ArgumentException(
                                                                           "Request to instantiate Java package as object"), LOGGER);
            }
            else
            {
                Org.Apache.Reef.Utilities.Diagnostics.Exceptions.Throw(new IllegalStateException(
                                                                           "Type hierarchy contained unknown node type!:" + n), LOGGER);
            }
            memo[n] = ip;
        }