You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@reef.apache.org by we...@apache.org on 2015/01/29 21:42:58 UTC
[14/31] incubator-reef git commit: [REEF-97] Add the REEF.NET code
base
http://git-wip-us.apache.org/repos/asf/incubator-reef/blob/2ae282de/lang/cs/Source/TANG/Tang/Implementations/InjectionPlan/InjectorImpl.cs
----------------------------------------------------------------------
diff --git a/lang/cs/Source/TANG/Tang/Implementations/InjectionPlan/InjectorImpl.cs b/lang/cs/Source/TANG/Tang/Implementations/InjectionPlan/InjectorImpl.cs
new file mode 100644
index 0000000..6144f3e
--- /dev/null
+++ b/lang/cs/Source/TANG/Tang/Implementations/InjectionPlan/InjectorImpl.cs
@@ -0,0 +1,1091 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.Linq;
+using System.Reflection;
+using System.Text;
+using System.Threading.Tasks;
+using Org.Apache.Reef.Utilities.Logging;
+using Org.Apache.Reef.Tang.Annotations;
+using Org.Apache.Reef.Tang.Exceptions;
+using Org.Apache.Reef.Tang.Interface;
+using Org.Apache.Reef.Tang.Types;
+using Org.Apache.Reef.Tang.Util;
+
+namespace Org.Apache.Reef.Tang.Implementations
+{
+ public class InjectorImpl : IInjector
+ {
+ private static readonly Logger LOGGER = Logger.GetLogger(typeof(InjectorImpl));
+
+ IDictionary<INamedParameterNode, object> namedParameterInstances = new MonotonicTreeMap<INamedParameterNode, object>();
+ private ICsClassHierarchy classHierarchy;
+ private IConfiguration configuration;
+ readonly IDictionary<IClassNode, Object> instances = new MonotonicTreeMap<IClassNode, Object>();
+ private Aspect aspect;
+ private readonly ISet<IInjectionFuture<object>> pendingFutures = new HashSet<IInjectionFuture<object>>();
+
+ static readonly InjectionPlan BUILDING = new BuildingInjectionPlan(null); //TODO anonymous class
+
+
+ private bool concurrentModificationGuard = false;
+
+ private void AssertNotConcurrent()
+ {
+ if (concurrentModificationGuard)
+ {
+ //TODO
+ //throw new ConcurrentModificationException("Detected attempt to use Injector from within an injected constructor!");
+ }
+ }
+ public InjectorImpl(IConfiguration c)
+ {
+ this.configuration = c;
+ this.classHierarchy = (ICsClassHierarchy)c.GetClassHierarchy();
+ }
+
+ 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
+ }
+
+ private object GetCachedInstance(IClassNode cn)
+ {
+ if (cn.GetFullName().Equals(ReflectionUtilities.GetAssemblyQualifiedName(typeof(IInjector))))
+ //if (cn.GetFullName().Equals(ReflectionUtilities.NonGenericFullName(typeof(IInjector))))
+ {
+ return this.ForkInjector();// TODO: We should be insisting on injection futures here! .forkInjector();
+ }
+ else
+ {
+ object t = null;
+
+ instances.TryGetValue(cn, out t);
+
+ if (t != null && t is IInjectionFuture<object>)
+ {
+ Org.Apache.Reef.Utilities.Diagnostics.Exceptions.Throw(new IllegalStateException("Found an injection future in getCachedInstance: " + cn), LOGGER);
+ }
+ return t;
+ }
+ }
+
+ private ConstructorInfo GetConstructor(IConstructorDef constructor)
+ {
+ Type clazz = (Type)this.classHierarchy.ClassForName(constructor.GetClassName());
+ IConstructorArg[] args = constructor.GetArgs().ToArray();
+ Type[] parameterTypes = new Type[args.Length];
+ for (int i = 0; i < args.Length; i++)
+ {
+ if (args[i].IsInjectionFuture())
+ {
+ parameterTypes[i] = typeof(IInjectionFuture<>).MakeGenericType(new Type[] { this.classHierarchy.ClassForName(args[i].Gettype()) });
+ }
+ else
+ {
+ parameterTypes[i] = this.classHierarchy.ClassForName(args[i].Gettype());
+ }
+ }
+
+ ConstructorInfo cons = clazz.GetConstructor(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, parameterTypes, null);
+ //TODO
+ //cons.setAccessible(true);
+
+ if (cons == null)
+ {
+ Org.Apache.Reef.Utilities.Diagnostics.Exceptions.Throw(new ApplicationException("Failed to look up constructor: " + constructor.ToString()), LOGGER);
+ }
+ return cons;
+ }
+
+ 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;
+ }
+
+ private InjectionPlan CreateSetInjectionPlan<T>(INode n, IDictionary<INode, InjectionPlan> memo, ISet<T> entries)
+ {
+ ISet<InjectionPlan> plans = new MonotonicHashSet<InjectionPlan>();
+ CreateInjectionPlanForCollectionElements(n, memo, entries, plans);
+ return new SetInjectionPlan(n, plans);
+ }
+
+ 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));
+ }
+ }
+ }
+
+ private InjectionPlan CreateListInjectionPlan<T>(INode n, IDictionary<INode, InjectionPlan> memo, IList<T> entries)
+ {
+ IList<InjectionPlan> plans = new List<InjectionPlan>();
+ CreateInjectionPlanForCollectionElements(n, memo, entries, plans);
+ return new ListInjectionPlan(n, plans);
+ }
+
+ 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);
+ }
+ }
+
+ 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;
+ }
+
+
+ private InjectionPlan WrapInjectionPlans(IClassNode infeasibleNode,
+ List<InjectionPlan> list, bool forceAmbiguous, int selectedIndex)
+ {
+ if (list.Count == 0)
+ {
+ return new Subplan(infeasibleNode, new InjectionPlan[] { });
+ }
+ else if ((!forceAmbiguous) && list.Count == 1)
+ {
+ return list[0];
+ }
+ else
+ {
+ return new Subplan(infeasibleNode, selectedIndex, list.ToArray());
+ }
+ }
+
+ private IClassNode ParseDefaultImplementation(IClassNode cn)
+ {
+ if (cn.GetDefaultImplementation() != null)
+ {
+ try
+ {
+ return (IClassNode)this.classHierarchy.GetNode(cn.GetDefaultImplementation());
+ }
+ catch (NameResolutionException e)
+ {
+ var ex = new IllegalStateException("After validation, " + cn + " had a bad default implementation named " + cn.GetDefaultImplementation(), e);
+ Org.Apache.Reef.Utilities.Diagnostics.Exceptions.CaughtAndThrow(ex, Level.Error, LOGGER);
+ }
+ }
+ return null;
+ }
+
+ private object ParseBoundNamedParameter(INamedParameterNode np)
+ {
+ ISet<object> boundSet = this.configuration.GetBoundSet((INamedParameterNode)np);
+ if (boundSet.Count != 0)
+ {
+ ISet<INode> ret3 = new MonotonicSet<INode>();
+ ISet<object> ret2 = new MonotonicSet<object>();
+ return ParseElementsInCollection(np, boundSet, ret3, ret2);
+ }
+
+ IList<object> boundList = this.configuration.GetBoundList((INamedParameterNode)np);
+ if (boundList != null && boundList.Count != 0)
+ {
+ IList<INode> ret3 = new List<INode>();
+ IList<object> ret2 = new List<object>();
+ return ParseElementsInCollection(np, boundList, ret3, ret2);
+ }
+
+ object ret = null;
+ if (namedParameterInstances.ContainsKey(np))
+ {
+ namedParameterInstances.TryGetValue(np, out ret);
+ }
+ else
+ {
+ string value = this.configuration.GetNamedParameter(np);
+ if (value == null)
+ {
+ ret = null;
+ }
+ else
+ {
+ try
+ {
+ ret = this.classHierarchy.Parse(np, value);
+ namedParameterInstances.Add(np, ret);
+ }
+ catch (BindException e)
+ {
+ Org.Apache.Reef.Utilities.Diagnostics.Exceptions.CaughtAndThrow(new IllegalStateException(
+ "Could not parse pre-validated value", e), Level.Error, LOGGER);
+ }
+ }
+ }
+ return ret;
+ }
+
+ private object ParseElementsInCollection(INamedParameterNode np, ICollection<object> boundSet, ICollection<INode> ret3, ICollection<object> ret2)
+ {
+ foreach (object o in boundSet)
+ {
+ if (o is string)
+ {
+ try
+ {
+ var r = this.classHierarchy.Parse(np, (string) o);
+ if (r is INode)
+ {
+ ret3.Add((INode) r);
+ }
+ else
+ {
+ ret2.Add(r);
+ }
+ }
+ catch (ParseException e)
+ {
+ Org.Apache.Reef.Utilities.Diagnostics.Exceptions.Caught(e, Level.Error, LOGGER);
+ var ex =
+ new IllegalStateException("Could not parse " + o + " which was passed into " + np +
+ " FIXME: Parsability is not currently checked by bindSetEntry(Node,String)");
+ Org.Apache.Reef.Utilities.Diagnostics.Exceptions.Throw(ex, LOGGER);
+ }
+ }
+ else if (o is INode)
+ {
+ var o2 = o as INode;
+ ret3.Add(o2);
+ }
+ else
+ {
+ var ex =
+ new IllegalStateException("Unexpected object " + o +
+ " in bound set. Should consist of nodes and strings");
+ Org.Apache.Reef.Utilities.Diagnostics.Exceptions.Throw(ex, LOGGER);
+ }
+ }
+ if (ret2.Count > 0 && ret3.Count == 0)
+ {
+ return ret2;
+ }
+ if (ret3.Count > 0 && ret2.Count == 0)
+ {
+ return ret3;
+ }
+ if (ret2.Count > 0 && ret3.Count > 0)
+ {
+ Org.Apache.Reef.Utilities.Diagnostics.Exceptions.Throw(new ApplicationException("Set contains different types of object"), LOGGER);
+ }
+ return ret2;
+ }
+
+ public object GetInstance(Type iface)
+ {
+ return GetInstance(ReflectionUtilities.GetAssemblyQualifiedName(iface));
+ }
+
+ public T GetInstance<T>() where T : class
+ {
+ return (T)GetInstance(ReflectionUtilities.GetAssemblyQualifiedName(typeof(T)));
+ }
+
+ private void CheckNamedParameter(Type t)
+ {
+ if (ReflectionUtilities.IsAssignableFromIgnoreGeneric(typeof (Name<>), t))
+ {
+ var ex = new InjectionException("GetInstance() called on Name "
+ + ReflectionUtilities.GetName(t)
+ + " Did you mean to call GetNamedInstance() instead?");
+ Org.Apache.Reef.Utilities.Diagnostics.Exceptions.Throw(ex, LOGGER);
+ }
+ }
+
+ 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;
+ }
+
+ public object GetInstance(string clazz)
+ {
+ CheckNamedParameter(ReflectionUtilities.GetTypeByName(clazz));
+ return GetInstance(classHierarchy.GetNode(clazz));
+ }
+
+ public U GetNamedInstance<T, U>(GenericType<T> clazz) where T : Name<U>
+ {
+ Type t = typeof(T);
+ return (U)GetInstance(classHierarchy.GetNode(t));
+ }
+
+ public U GetNamedInstance<T, U>() where T : Name<U>
+ {
+ Type t = typeof(T);
+ return (U)GetInstance(classHierarchy.GetNode(t));
+ }
+
+ public object GetNamedInstance(Type t)
+ {
+ if (!ReflectionUtilities.IsAssignableFromIgnoreGeneric(typeof (Name<>), t))
+ {
+ var ex = new ApplicationException(string.Format(CultureInfo.CurrentCulture, "The parameter {0} is not inherit from Name<>", t));
+ Org.Apache.Reef.Utilities.Diagnostics.Exceptions.Throw(ex, LOGGER);
+ }
+ return GetInstance(classHierarchy.GetNode(t));
+ }
+
+ public InjectionPlan GetInjectionPlan(Type name)
+ {
+ return GetInjectionPlan(this.classHierarchy.GetNode(name));
+ }
+
+ 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
+ }
+
+ public bool IsInjectable(string name)
+ {
+ return GetInjectionPlan(this.classHierarchy.GetNode(name)).IsInjectable();
+ }
+
+ public bool IsParameterSet(string name)
+ {
+ InjectionPlan p = GetInjectionPlan(classHierarchy.GetNode(name));
+ return p.IsInjectable();
+ }
+
+ public bool IsInjectable(Type clazz)
+ {
+ AssertNotConcurrent();
+ try
+ {
+ return IsInjectable(ReflectionUtilities.GetAssemblyQualifiedName(clazz));
+ }
+ catch (NameResolutionException e)
+ {
+ Org.Apache.Reef.Utilities.Diagnostics.Exceptions.Caught(e, Level.Error, LOGGER);
+ Org.Apache.Reef.Utilities.Diagnostics.Exceptions.Throw(new IllegalStateException("Could not round trip " + clazz + " through ClassHierarchy", e), LOGGER);
+ return false;
+ }
+ }
+
+ public bool IsParameterSet(Type name)
+ {
+ return IsParameterSet(ReflectionUtilities.GetAssemblyQualifiedName(name));
+ }
+
+ public void BindAspect(Aspect a)
+ {
+ if (aspect != null)
+ {
+ Org.Apache.Reef.Utilities.Diagnostics.Exceptions.Throw(new BindException("Attempt to re-bind aspect! old=" + aspect + " new=" + a), LOGGER);
+ }
+ aspect = a;
+ }
+
+ public Aspect GetAspect()
+ {
+ return aspect;
+ }
+
+ public IInjector ForkInjector()
+ {
+ try
+ {
+ return ForkInjector(new ConfigurationImpl[0]);
+ }
+ catch (BindException e)
+ {
+ Org.Apache.Reef.Utilities.Diagnostics.Exceptions.Caught(e, Level.Error, LOGGER);
+ Org.Apache.Reef.Utilities.Diagnostics.Exceptions.Throw(new IllegalStateException("Error in forking injector.", e), LOGGER);
+ return null;
+ }
+ }
+
+ public IInjector ForkInjector(IConfiguration[] configurations)
+ {
+ InjectorImpl ret;
+ ret = Copy(this, configurations);
+ return ret;
+ }
+
+ private static InjectorImpl Copy(InjectorImpl old, IConfiguration[] configurations)
+ {
+ InjectorImpl injector = null;
+ try
+ {
+ IConfigurationBuilder cb = old.configuration.newBuilder();
+ foreach (IConfiguration c in configurations)
+ {
+ cb.AddConfiguration(c);
+ }
+ injector = new InjectorImpl(cb.Build());
+ }
+ catch (BindException e)
+ {
+ Org.Apache.Reef.Utilities.Diagnostics.Exceptions.Caught(e, Level.Error, LOGGER);
+ Org.Apache.Reef.Utilities.Diagnostics.Exceptions.Throw(new IllegalStateException("Unexpected error copying configuration!", e), LOGGER);
+ }
+
+ foreach (IClassNode cn in old.instances.Keys)
+ {
+ if (cn.GetFullName().Equals(ReflectionUtilities.GetAssemblyQualifiedName(typeof(IInjector)))
+ || cn.GetFullName().Equals(ReflectionUtilities.GetAssemblyQualifiedName(typeof(InjectorImpl))))
+ {
+ // This would imply that we're treating injector as a singleton somewhere. It should be copied fresh each time.
+ Org.Apache.Reef.Utilities.Diagnostics.Exceptions.Throw(new IllegalStateException(""), LOGGER);
+ }
+ try
+ {
+ IClassNode new_cn = (IClassNode)injector.classHierarchy.GetNode(cn.GetFullName());
+
+ object o = null;
+ old.instances.TryGetValue(cn, out o);
+ if (o != null)
+ {
+ injector.instances.Add(new_cn, o);
+ }
+ }
+ catch (BindException e)
+ {
+ Org.Apache.Reef.Utilities.Diagnostics.Exceptions.Caught(e, Level.Error, LOGGER);
+ Org.Apache.Reef.Utilities.Diagnostics.Exceptions.Throw(new IllegalStateException("Could not resolve name "
+ + cn.GetFullName() + " when copying injector", e), LOGGER);
+ }
+ }
+
+ foreach (INamedParameterNode np in old.namedParameterInstances.Keys)
+ {
+ // if (!builder.namedParameters.containsKey(np)) {
+ Object o = null;
+ old.namedParameterInstances.TryGetValue(np, out o);
+ INamedParameterNode new_np = (INamedParameterNode)injector.classHierarchy.GetNode(np.GetFullName());
+ injector.namedParameterInstances.Add(new_np, o);
+ }
+
+ // Fork the aspect (if any)
+ if (old.aspect != null)
+ {
+ injector.BindAspect(old.aspect.CreateChildAspect());
+ }
+ return injector;
+ }
+
+ void BindVolatileInstanceNoCopy<T>(GenericType<T> c, T o)
+ {
+ AssertNotConcurrent();
+ INode n = this.classHierarchy.GetNode(typeof(T));
+ if (n is IClassNode)
+ {
+ IClassNode cn = (IClassNode) n;
+ object old = GetCachedInstance(cn);
+ if (old != null) {
+ Org.Apache.Reef.Utilities.Diagnostics.Exceptions.Throw(new BindException("Attempt to re-bind instance. Old value was "
+ + old + " new value is " + o), LOGGER);
+ }
+ instances.Add(cn, o);
+ } else {
+ Org.Apache.Reef.Utilities.Diagnostics.Exceptions.Throw(new ArgumentException("Expected Class but got " + c
+ + " (probably a named parameter)."), LOGGER);
+ }
+ }
+
+ //void BindVolatileParameterNoCopy(Class<? extends Name<T>> c, T o)
+ void BindVolatileParameterNoCopy<U, T>(GenericType<U> c, T o)
+ where U : Name<T>
+ {
+ INode n = this.classHierarchy.GetNode(typeof(U));
+ if (n is INamedParameterNode)
+ {
+ INamedParameterNode np = (INamedParameterNode) n;
+ Object old = this.configuration.GetNamedParameter(np);
+ if(old != null)
+ {
+ // XXX need to get the binding site here!
+ var ex = new BindException(
+ "Attempt to re-bind named parameter " + ReflectionUtilities.GetAssemblyQualifiedName(typeof(U)) + ". Old value was [" + old
+ + "] new value is [" + o + "]");
+ Org.Apache.Reef.Utilities.Diagnostics.Exceptions.Throw(ex, LOGGER);
+ }
+ try
+ {
+ namedParameterInstances.Add(np, o);
+ }
+ catch (ArgumentException e)
+ {
+ Org.Apache.Reef.Utilities.Diagnostics.Exceptions.Caught(e, Level.Error, LOGGER);
+ var ex = new BindException(
+ "Attempt to re-bind named parameter " + ReflectionUtilities.GetAssemblyQualifiedName(typeof(U)) + ". Old value was [" + old
+ + "] new value is [" + o + "]");
+ Org.Apache.Reef.Utilities.Diagnostics.Exceptions.Throw(ex, LOGGER);
+ }
+ }
+ else
+ {
+ var ex = new ArgumentException("Expected Name, got " + typeof(U) + " (probably a class)");
+ Org.Apache.Reef.Utilities.Diagnostics.Exceptions.Throw(ex, LOGGER);
+ }
+ }
+
+ //public <T> void bindVolatileInstance(Class<T> c, T o) throws BindException {
+ public void BindVolatileInstance<T>(GenericType<T> iface, T inst)
+ {
+ BindVolatileInstanceNoCopy(iface, inst);
+ }
+
+ /// <summary>
+ /// Binds the volatile instance.
+ /// </summary>
+ /// <typeparam name="T"></typeparam>
+ /// <param name="inst">The inst.</param>
+ public void BindVolatileInstance<T>(T inst)
+ {
+ BindVolatileInstance<T>(GenericType<T>.Class, inst);
+ }
+
+ /// <summary>
+ /// Binds the volatile parameter.
+ /// </summary>
+ /// <typeparam name="U"></typeparam>
+ /// <typeparam name="T"></typeparam>
+ /// <param name="iface">The iface.</param>
+ /// <param name="inst">The inst.</param>
+ public void BindVolatileParameter<U, T>(GenericType<U> iface, T inst) where U : Name<T>
+ {
+ BindVolatileParameterNoCopy(iface, inst);
+ }
+
+ /// <summary>
+ /// Binds the volatile parameter.
+ /// </summary>
+ /// <typeparam name="U"></typeparam>
+ /// <typeparam name="T"></typeparam>
+ /// <param name="inst">The inst.</param>
+ public void BindVolatileParameter<U, T>(T inst) where U : Name<T>
+ {
+ BindVolatileParameter(GenericType<U>.Class, inst);
+ }
+
+ //public T GetNamedParameter<U, T>(GenericType<U> name) where U : Name<T>
+ //{
+ // return (T)GetNamedInstance(typeof(U));
+ //}
+
+ //public IInjector CreateChildInjector(IConfiguration[] configurations)
+ //{
+ // return ForkInjector(configurations);
+ //}
+ /// <summary>
+ /// Gets the injection plan for a given class name
+ /// </summary>
+ /// <param name="name">The name.</param>
+ /// <returns></returns>
+ public InjectionPlan GetInjectionPlan(string name)
+ {
+ return GetInjectionPlan(this.classHierarchy.GetNode(name));
+
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-reef/blob/2ae282de/lang/cs/Source/TANG/Tang/Implementations/InjectionPlan/ListInjectionPlan.cs
----------------------------------------------------------------------
diff --git a/lang/cs/Source/TANG/Tang/Implementations/InjectionPlan/ListInjectionPlan.cs b/lang/cs/Source/TANG/Tang/Implementations/InjectionPlan/ListInjectionPlan.cs
new file mode 100644
index 0000000..8a5ad49
--- /dev/null
+++ b/lang/cs/Source/TANG/Tang/Implementations/InjectionPlan/ListInjectionPlan.cs
@@ -0,0 +1,117 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+using System.Collections.Generic;
+using System.Text;
+using Org.Apache.Reef.Tang.Types;
+
+namespace Org.Apache.Reef.Tang.Implementations
+{
+ public class ListInjectionPlan : InjectionPlan
+ {
+ private readonly IList<InjectionPlan> entries = new List<InjectionPlan>();
+ private readonly int numAlternatives;
+ private readonly bool isAmbiguous;
+ private readonly bool isInjectable;
+
+ public ListInjectionPlan(INode name, IList<InjectionPlan> entries) : base(name)
+ {
+ foreach (InjectionPlan ip in entries)
+ {
+ this.entries.Add(ip);
+ }
+ int numAlternatives = 1;
+ bool isAmbiguous = false;
+ bool isInjectable = true;
+ foreach (InjectionPlan ip in entries)
+ {
+ numAlternatives *= ip.GetNumAlternatives();
+ isAmbiguous |= ip.IsAmbiguous();
+ isInjectable &= ip.IsInjectable();
+ }
+ this.numAlternatives = numAlternatives;
+ this.isAmbiguous = isAmbiguous;
+ this.isInjectable = isInjectable;
+ }
+
+ public override int GetNumAlternatives()
+ {
+ return numAlternatives;
+ }
+
+ public override bool IsAmbiguous()
+ {
+ return isAmbiguous;
+ }
+
+ public override bool IsInjectable()
+ {
+ return isInjectable;
+ }
+
+ public IList<InjectionPlan> GetEntryPlans()
+ {
+ return new List<InjectionPlan>(this.entries);
+ }
+
+ public override string ToAmbiguousInjectString()
+ {
+ StringBuilder sb = new StringBuilder(GetNode().GetFullName() + "(list) includes ambiguous plans [");
+ foreach (InjectionPlan ip in entries)
+ {
+ if (ip.IsAmbiguous())
+ {
+ sb.Append("\n" + ip.ToAmbiguousInjectString());
+ }
+ }
+ sb.Append("]");
+ return sb.ToString();
+ }
+
+ public override string ToInfeasibleInjectString()
+ {
+ StringBuilder sb = new StringBuilder(GetNode().GetFullName() + "(list) includes infeasible plans [");
+ foreach (InjectionPlan ip in entries)
+ {
+ if (!ip.IsFeasible())
+ {
+ sb.Append("\n" + ip.ToInfeasibleInjectString());
+ }
+ }
+ sb.Append("\n]");
+ return sb.ToString();
+ }
+
+ public override bool IsInfeasibleLeaf()
+ {
+ return false;
+ }
+
+ public override string ToShallowString()
+ {
+ StringBuilder sb = new StringBuilder("list { ");
+ foreach (InjectionPlan ip in entries)
+ {
+ sb.Append("\n" + ip.ToShallowString());
+ }
+ sb.Append("\n } ");
+ return null;
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-reef/blob/2ae282de/lang/cs/Source/TANG/Tang/Implementations/InjectionPlan/SetInjectionPlan.cs
----------------------------------------------------------------------
diff --git a/lang/cs/Source/TANG/Tang/Implementations/InjectionPlan/SetInjectionPlan.cs b/lang/cs/Source/TANG/Tang/Implementations/InjectionPlan/SetInjectionPlan.cs
new file mode 100644
index 0000000..1b530b6
--- /dev/null
+++ b/lang/cs/Source/TANG/Tang/Implementations/InjectionPlan/SetInjectionPlan.cs
@@ -0,0 +1,122 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+using System.Collections.Generic;
+using System.Text;
+using Org.Apache.Reef.Tang.Types;
+using Org.Apache.Reef.Tang.Util;
+
+namespace Org.Apache.Reef.Tang.Implementations
+{
+ public class SetInjectionPlan : InjectionPlan
+ {
+ private readonly ISet<InjectionPlan> entries = new MonotonicHashSet<InjectionPlan>();
+ private readonly int numAlternatives;
+ private readonly bool isAmbiguous;
+ private readonly bool isInjectable;
+
+ public SetInjectionPlan(INode name, ISet<InjectionPlan> entries) : base(name)
+ {
+ foreach (InjectionPlan ip in entries)
+ {
+ this.entries.Add(ip);
+ }
+ int numAlternatives = 1;
+ bool isAmbiguous = false;
+ bool isInjectable = true;
+ foreach (InjectionPlan ip in entries)
+ {
+ numAlternatives *= ip.GetNumAlternatives();
+ isAmbiguous |= ip.IsAmbiguous();
+ isInjectable &= ip.IsInjectable();
+ }
+ this.numAlternatives = numAlternatives;
+ this.isAmbiguous = isAmbiguous;
+ this.isInjectable = isInjectable;
+ }
+
+ public override int GetNumAlternatives()
+ {
+ return numAlternatives;
+ }
+
+ public override bool IsAmbiguous()
+ {
+ return isAmbiguous;
+ }
+
+ public override bool IsInjectable()
+ {
+ return isInjectable;
+ }
+
+ //public override bool HasFutureDependency()
+ //{
+ // return false;
+ //}
+
+ public ISet<InjectionPlan> GetEntryPlans()
+ {
+ return new MonotonicHashSet<InjectionPlan>(this.entries);
+ }
+
+ public override string ToAmbiguousInjectString()
+ {
+ StringBuilder sb = new StringBuilder(GetNode().GetFullName() + "(set) includes ambiguous plans [");
+ foreach (InjectionPlan ip in entries)
+ {
+ if(ip.IsAmbiguous())
+ {
+ sb.Append("\n" + ip.ToAmbiguousInjectString());
+ }
+ }
+ sb.Append("]");
+ return sb.ToString();
+ }
+
+ public override string ToInfeasibleInjectString()
+ {
+ StringBuilder sb = new StringBuilder(GetNode().GetFullName() + "(set) includes infeasible plans [");
+ foreach (InjectionPlan ip in entries)
+ {
+ if(!ip.IsFeasible())
+ {
+ sb.Append("\n" + ip.ToInfeasibleInjectString());
+ }
+ }
+ sb.Append("\n]");
+ return sb.ToString();
+ }
+
+ public override bool IsInfeasibleLeaf()
+ {
+ return false;
+ }
+
+ public override string ToShallowString()
+ {
+ StringBuilder sb = new StringBuilder("set { ");
+ foreach (InjectionPlan ip in entries)
+ {
+ sb.Append("\n" + ip.ToShallowString());
+ }
+ sb.Append("\n } ");
+ return null;
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-reef/blob/2ae282de/lang/cs/Source/TANG/Tang/Implementations/InjectionPlan/Subplan.cs
----------------------------------------------------------------------
diff --git a/lang/cs/Source/TANG/Tang/Implementations/InjectionPlan/Subplan.cs b/lang/cs/Source/TANG/Tang/Implementations/InjectionPlan/Subplan.cs
new file mode 100644
index 0000000..b0b0229
--- /dev/null
+++ b/lang/cs/Source/TANG/Tang/Implementations/InjectionPlan/Subplan.cs
@@ -0,0 +1,235 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+using System;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.Linq;
+using System.Text;
+using Org.Apache.Reef.Utilities.Logging;
+using Org.Apache.Reef.Tang.Exceptions;
+using Org.Apache.Reef.Tang.Types;
+
+namespace Org.Apache.Reef.Tang.Implementations
+{
+ public class Subplan : InjectionPlan
+ {
+ private static readonly Logger LOGGER = Logger.GetLogger(typeof(Subplan));
+
+ InjectionPlan[] alternatives; //all implementatios on the same interface
+ int numAlternatives;
+ int selectedIndex; //the implementation that is bound
+
+ public Subplan(INode n, int selectedIndex, InjectionPlan[] alternatives)
+ : base(n)
+ {
+ this.alternatives = alternatives;
+ if (selectedIndex < -1 || selectedIndex >= alternatives.Length)
+ {
+ Org.Apache.Reef.Utilities.Diagnostics.Exceptions.Throw(new IndexOutOfRangeException(), LOGGER);
+ }
+ this.selectedIndex = selectedIndex;
+ if (selectedIndex != -1) //one was bound
+ {
+ this.numAlternatives = alternatives[selectedIndex].GetNumAlternatives();
+ }
+ else // no one was bound, but anyone could be used
+ {
+ int numAlternatives = 0;
+ foreach (InjectionPlan a in alternatives)
+ {
+ numAlternatives += a.GetNumAlternatives();
+ }
+ this.numAlternatives = numAlternatives;
+ }
+ }
+
+ public new ICollection<InjectionPlan> GetChildren()
+ {
+ return new ReadOnlyCollection<InjectionPlan>(this.alternatives.OfType<InjectionPlan>().ToList());
+ }
+
+ public Subplan(INode n, InjectionPlan[] alternatives)
+ : this(n, -1, alternatives)
+ {
+ }
+
+ public override int GetNumAlternatives()
+ {
+ return this.numAlternatives;
+ }
+
+ public override bool IsAmbiguous()
+ {
+ if (selectedIndex == -1)
+ {
+ return true;
+ }
+ return alternatives[selectedIndex].IsAmbiguous();
+ }
+
+ public override bool IsInjectable()
+ {
+ if (selectedIndex == -1)
+ {
+ return false;
+ }
+ else
+ {
+ return alternatives[selectedIndex].IsInjectable();
+ }
+ }
+
+ public override string ToString()
+ {
+ if (alternatives.Length == 1)
+ {
+ return GetNode().GetName() + " = " + alternatives[0];
+ }
+ else if (alternatives.Length == 0)
+ {
+ return GetNode().GetName() + ": no injectable constructors";
+ }
+ StringBuilder sb = new StringBuilder("[");
+ sb.Append(GetNode().GetName() + " = " + alternatives[0]);
+ for (int i = 1; i < alternatives.Length; i++)
+ {
+ sb.Append(" | " + alternatives[i]);
+ }
+ sb.Append("]");
+ return sb.ToString();
+ }
+
+ public override string ToShallowString()
+ {
+ if (alternatives.Length == 1)
+ {
+ return GetNode().GetName() + " = " + alternatives[0].ToShallowString();
+ }
+ else if (alternatives.Length == 0)
+ {
+ return GetNode().GetName() + ": no injectable constructors";
+ }
+ StringBuilder sb = new StringBuilder("[");
+ sb.Append(GetNode().GetName() + " = " + alternatives[0].ToShallowString());
+ for (int i = 1; i < alternatives.Length; i++)
+ {
+ sb.Append(" | " + alternatives[i].ToShallowString());
+ }
+ sb.Append("]");
+ return sb.ToString();
+ }
+
+ public int GetSelectedIndex()
+ {
+ return selectedIndex;
+ }
+
+ public InjectionPlan GetDelegatedPlan()
+ {
+ if (selectedIndex != -1)
+ {
+ return alternatives[selectedIndex];
+ }
+ Org.Apache.Reef.Utilities.Diagnostics.Exceptions.Throw(new IllegalStateException("Error in getting GetDelegatedPlan."), LOGGER);
+ return null;
+ }
+
+ //public override bool HasFutureDependency()
+ //{
+ // if (selectedIndex == -1)
+ // {
+ // throw new IllegalStateException("hasFutureDependency() called on ambiguous subplan!");
+ // }
+ // return alternatives[selectedIndex].HasFutureDependency();
+ //}
+
+ public override string ToAmbiguousInjectString()
+ {
+ if (alternatives.Length == 1)
+ {
+ return alternatives[0].ToAmbiguousInjectString();
+ }
+ else if (selectedIndex != -1)
+ {
+ return alternatives[selectedIndex].ToAmbiguousInjectString();
+ }
+ else
+ {
+ IList<InjectionPlan> alts = new List<InjectionPlan>();
+ IList<InjectionPlan> ambig = new List<InjectionPlan>();
+ foreach (InjectionPlan alt in alternatives)
+ {
+ if (alt.IsFeasible())
+ {
+ alts.Add(alt);
+ }
+ if (alt.IsAmbiguous())
+ {
+ ambig.Add(alt);
+ }
+ }
+ StringBuilder sb = new StringBuilder("Ambiguous subplan " + GetNode().GetFullName());
+ foreach (InjectionPlan alt in alts)
+ {
+ sb.Append("\n " + alt.ToShallowString() + " ");
+ }
+ foreach (InjectionPlan alt in ambig)
+ {
+ sb.Append("\n " + alt.ToShallowString() + " ");
+ }
+ sb.Append("\n]");
+ return sb.ToString();
+ }
+ }
+
+ public override string ToInfeasibleInjectString()
+ {
+ if (alternatives.Length == 1)
+ {
+ return alternatives[0].ToInfeasibleInjectString();
+ }
+ else if (alternatives.Length == 0)
+ {
+ return "No known implementations / injectable constructors for "
+ + this.GetNode().GetFullName();
+ }
+ else if (selectedIndex != -1)
+ {
+ return alternatives[selectedIndex].ToInfeasibleInjectString();
+ }
+ else
+ {
+ return "Multiple infeasible plans: " + ToPrettyString();
+ }
+ }
+
+ public InjectionPlan[] GetPlans()
+ {
+ InjectionPlan[] copy = new InjectionPlan[alternatives.Length];
+ Array.Copy(alternatives, copy, alternatives.Length); // not sure if it does deep copy??
+ return copy;
+ }
+
+ public override bool IsInfeasibleLeaf()
+ {
+ return false;
+ }
+
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-reef/blob/2ae282de/lang/cs/Source/TANG/Tang/Implementations/Tang/TangFactory.cs
----------------------------------------------------------------------
diff --git a/lang/cs/Source/TANG/Tang/Implementations/Tang/TangFactory.cs b/lang/cs/Source/TANG/Tang/Implementations/Tang/TangFactory.cs
new file mode 100644
index 0000000..c54f562
--- /dev/null
+++ b/lang/cs/Source/TANG/Tang/Implementations/Tang/TangFactory.cs
@@ -0,0 +1,30 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+using Org.Apache.Reef.Tang.Interface;
+
+namespace Org.Apache.Reef.Tang.Implementations
+{
+ public class TangFactory
+ {
+ public static ITang GetTang()
+ {
+ return new TangImpl();
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-reef/blob/2ae282de/lang/cs/Source/TANG/Tang/Implementations/Tang/TangImpl.cs
----------------------------------------------------------------------
diff --git a/lang/cs/Source/TANG/Tang/Implementations/Tang/TangImpl.cs b/lang/cs/Source/TANG/Tang/Implementations/Tang/TangImpl.cs
new file mode 100644
index 0000000..5e0181b
--- /dev/null
+++ b/lang/cs/Source/TANG/Tang/Implementations/Tang/TangImpl.cs
@@ -0,0 +1,201 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+using System;
+using System.Collections.Generic;
+using Org.Apache.Reef.Utilities.Logging;
+using Org.Apache.Reef.Tang.Exceptions;
+using Org.Apache.Reef.Tang.Formats;
+using Org.Apache.Reef.Tang.Interface;
+using Org.Apache.Reef.Tang.Util;
+
+namespace Org.Apache.Reef.Tang.Implementations
+{
+ public class TangImpl : ITang
+ {
+ private static readonly Logger LOGGER = Logger.GetLogger(typeof(TangImpl));
+
+ private static IDictionary<SetValuedKey, ICsClassHierarchy> defaultClassHierarchy = new Dictionary<SetValuedKey, ICsClassHierarchy>();
+
+ public IInjector NewInjector()
+ {
+ try
+ {
+ return NewInjector(new ConfigurationImpl[] {});
+ }
+ catch (BindException e)
+ {
+ Org.Apache.Reef.Utilities.Diagnostics.Exceptions.Caught(e, Level.Error, LOGGER);
+ Org.Apache.Reef.Utilities.Diagnostics.Exceptions.Throw(new IllegalStateException("Unexpected error from empty configuration", e), LOGGER);
+ return null;
+ }
+ }
+
+ public IInjector NewInjector(string[] assemblies, string configurationFileName)
+ {
+ ITang tang = TangFactory.GetTang();
+ ICsConfigurationBuilder cb1 = tang.NewConfigurationBuilder(assemblies);
+ ConfigurationFile.AddConfigurationFromFile(cb1, configurationFileName);
+ IConfiguration conf = cb1.Build();
+
+ IInjector injector = tang.NewInjector(conf);
+ return injector;
+ }
+
+ public ICsConfigurationBuilder NewConfigurationBuilder(IConfiguration conf)
+ {
+ return NewConfigurationBuilder(new IConfiguration[] { conf });
+ }
+
+ //public IInjector NewInjector(string[] assemblies, IDictionary<string, string> configurations)
+ //{
+ // ITang tang = TangFactory.GetTang();
+ // ICsConfigurationBuilder cb1 = tang.NewConfigurationBuilder(assemblies);
+ // ConfigurationFile.ProcessConfigData(cb1, configurations);
+ // IConfiguration conf = cb1.Build();
+
+ // IInjector injector = tang.NewInjector(conf);
+ // return injector;
+ //}
+
+ public IInjector NewInjector(string[] assemblies, IDictionary<string, string> configurations)
+ {
+ IList<KeyValuePair<string, string>> conf = new List<KeyValuePair<string, string>>();
+ foreach (KeyValuePair<string, string> kp in configurations)
+ {
+ conf.Add(kp);
+ }
+ return NewInjector(assemblies, conf);
+ }
+
+ public IInjector NewInjector(string[] assemblies, IList<KeyValuePair<string, string>> configurations)
+ {
+ ITang tang = TangFactory.GetTang();
+ ICsConfigurationBuilder cb1 = tang.NewConfigurationBuilder(assemblies);
+ ConfigurationFile.ProcessConfigData(cb1, configurations);
+ IConfiguration conf = cb1.Build();
+
+ IInjector injector = tang.NewInjector(conf);
+ return injector;
+ }
+
+ public IInjector NewInjector(IConfiguration[] confs)
+ {
+ return new InjectorImpl(new CsConfigurationBuilderImpl(confs).Build());
+ }
+
+ public IInjector NewInjector(IConfiguration conf)
+ {
+ //return new InjectorImpl(conf);
+ try
+ {
+ return NewInjector(new ConfigurationImpl[] { (ConfigurationImpl)conf });
+ }
+ catch (BindException e)
+ {
+ Org.Apache.Reef.Utilities.Diagnostics.Exceptions.Caught(e, Level.Error, LOGGER);
+ Org.Apache.Reef.Utilities.Diagnostics.Exceptions.Throw(new IllegalStateException("Unexpected error cloning configuration", e), LOGGER);
+ return null;
+ }
+ }
+
+ public IClassHierarchy GetClassHierarchy(string[] assemblies)
+ {
+ return GetDefaultClassHierarchy(assemblies, new Type[] { });
+ }
+
+ public ICsClassHierarchy GetDefaultClassHierarchy()
+ {
+ return GetDefaultClassHierarchy(new string[0], new Type[0]);
+ }
+
+ public ICsClassHierarchy GetDefaultClassHierarchy(string[] assemblies, Type[] parameterParsers)
+ {
+ SetValuedKey key = new SetValuedKey(assemblies, parameterParsers);
+
+ ICsClassHierarchy ret = null;
+ defaultClassHierarchy.TryGetValue(key, out ret);
+ if (ret == null)
+ {
+ ret = new ClassHierarchyImpl(assemblies, parameterParsers);
+ defaultClassHierarchy.Add(key, ret);
+ }
+ return ret;
+ }
+
+ public ICsConfigurationBuilder NewConfigurationBuilder()
+ {
+ try
+ {
+ return NewConfigurationBuilder(new string[0], new IConfiguration[0], new Type[0]);
+ }
+ catch (BindException e)
+ {
+ Org.Apache.Reef.Utilities.Diagnostics.Exceptions.Caught(e, Level.Error, LOGGER);
+ Org.Apache.Reef.Utilities.Diagnostics.Exceptions.Throw(new IllegalStateException(
+ "Caught unexpeceted bind exception! Implementation bug.", e), LOGGER);
+ return null;
+ }
+ }
+
+ public ICsConfigurationBuilder NewConfigurationBuilder(string[] assemblies)
+ {
+ try
+ {
+ return NewConfigurationBuilder(assemblies, new IConfiguration[0], new Type[0]);
+ }
+ catch (BindException e)
+ {
+ Org.Apache.Reef.Utilities.Diagnostics.Exceptions.Caught(e, Level.Error, LOGGER);
+ Org.Apache.Reef.Utilities.Diagnostics.Exceptions.Throw(new IllegalStateException(
+ "Caught unexpeceted bind exception! Implementation bug.", e), LOGGER);
+ return null;
+ }
+ }
+
+ public IConfigurationBuilder NewConfigurationBuilder(IClassHierarchy classHierarchy)
+ {
+ return new ConfigurationBuilderImpl(classHierarchy);
+ }
+
+ public ICsConfigurationBuilder NewConfigurationBuilder(ICsClassHierarchy classHierarchy)
+ {
+ return new CsConfigurationBuilderImpl(classHierarchy);
+ }
+
+ public ICsConfigurationBuilder NewConfigurationBuilder(IConfiguration[] confs)
+ {
+ return NewConfigurationBuilder(new string[0], confs, new Type[0]);
+ }
+
+ public ICsConfigurationBuilder NewConfigurationBuilder(string[] assemblies, IConfiguration[] confs, Type[] parameterParsers)
+ {
+ return new CsConfigurationBuilderImpl(assemblies, confs, parameterParsers);
+ }
+
+ public ICsConfigurationBuilder NewConfigurationBuilder(Type[] parameterParsers)
+ {
+ return NewConfigurationBuilder(new string[0], new IConfiguration[0], parameterParsers);
+ }
+
+ public static void Reset()
+ {
+ defaultClassHierarchy = new Dictionary<SetValuedKey, ICsClassHierarchy>();
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-reef/blob/2ae282de/lang/cs/Source/TANG/Tang/Interface/IAspect.cs
----------------------------------------------------------------------
diff --git a/lang/cs/Source/TANG/Tang/Interface/IAspect.cs b/lang/cs/Source/TANG/Tang/Interface/IAspect.cs
new file mode 100644
index 0000000..2c19897
--- /dev/null
+++ b/lang/cs/Source/TANG/Tang/Interface/IAspect.cs
@@ -0,0 +1,31 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+using System.Reflection;
+using Org.Apache.Reef.Tang.Implementations;
+using Org.Apache.Reef.Tang.Types;
+
+namespace Org.Apache.Reef.Tang.Interface
+{
+ public interface Aspect
+ {
+ object Inject(IConstructorDef def, ConstructorInfo constructor, object[] args);
+ void InjectionFutureInstantiated<T>(IInjectionFuture<T> f, object t);
+ Aspect CreateChildAspect();
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-reef/blob/2ae282de/lang/cs/Source/TANG/Tang/Interface/IClassHierarchy.cs
----------------------------------------------------------------------
diff --git a/lang/cs/Source/TANG/Tang/Interface/IClassHierarchy.cs b/lang/cs/Source/TANG/Tang/Interface/IClassHierarchy.cs
new file mode 100644
index 0000000..7428942
--- /dev/null
+++ b/lang/cs/Source/TANG/Tang/Interface/IClassHierarchy.cs
@@ -0,0 +1,30 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+using Org.Apache.Reef.Tang.Types;
+
+namespace Org.Apache.Reef.Tang.Interface
+{
+ public interface IClassHierarchy
+ {
+ INode GetNode(string fullName);
+ INode GetNamespace();
+ bool IsImplementation(IClassNode inter, IClassNode impl);
+ IClassHierarchy Merge(IClassHierarchy ch);
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-reef/blob/2ae282de/lang/cs/Source/TANG/Tang/Interface/IConfiguration.cs
----------------------------------------------------------------------
diff --git a/lang/cs/Source/TANG/Tang/Interface/IConfiguration.cs b/lang/cs/Source/TANG/Tang/Interface/IConfiguration.cs
new file mode 100644
index 0000000..6903d19
--- /dev/null
+++ b/lang/cs/Source/TANG/Tang/Interface/IConfiguration.cs
@@ -0,0 +1,49 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Org.Apache.Reef.Tang.Types;
+
+namespace Org.Apache.Reef.Tang.Interface
+{
+ public interface IConfiguration
+ {
+ IConfigurationBuilder newBuilder();
+ string GetNamedParameter(INamedParameterNode np);
+ IClassHierarchy GetClassHierarchy();
+
+ ISet<Object> GetBoundSet(INamedParameterNode np); //named parameter for a set
+ IList<Object> GetBoundList(INamedParameterNode np); //named parameter for a list
+
+ IClassNode GetBoundConstructor(IClassNode cn);
+ IClassNode GetBoundImplementation(IClassNode cn);
+ IConstructorDef GetLegacyConstructor(IClassNode cn);
+
+ ICollection<IClassNode> GetBoundImplementations();
+ ICollection<IClassNode> GetBoundConstructors();
+ ICollection<INamedParameterNode> GetNamedParameters();
+ ICollection<IClassNode> GetLegacyConstructors();
+
+ IEnumerator<KeyValuePair<INamedParameterNode, object>> GetBoundSets();
+ IDictionary<INamedParameterNode, IList<object>> GetBoundList();
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-reef/blob/2ae282de/lang/cs/Source/TANG/Tang/Interface/IConfigurationBuilder.cs
----------------------------------------------------------------------
diff --git a/lang/cs/Source/TANG/Tang/Interface/IConfigurationBuilder.cs b/lang/cs/Source/TANG/Tang/Interface/IConfigurationBuilder.cs
new file mode 100644
index 0000000..640b11d
--- /dev/null
+++ b/lang/cs/Source/TANG/Tang/Interface/IConfigurationBuilder.cs
@@ -0,0 +1,54 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Org.Apache.Reef.Tang.Types;
+
+namespace Org.Apache.Reef.Tang.Interface
+{
+ public interface IConfigurationBuilder
+ {
+ void AddConfiguration(IConfiguration c);
+ IClassHierarchy GetClassHierarchy();
+ IConfiguration Build();
+ void Bind(string iface, string impl);
+ void Bind(INode key, INode value);
+
+ void BindConstructor(IClassNode k, IClassNode v); //v extended from ExternalConstructor
+ string ClassPrettyDefaultString(string longName);
+ string ClassPrettyDescriptionString(string longName);
+
+ void RegisterLegacyConstructor(IClassNode cn, IList<IClassNode> args);
+ void RegisterLegacyConstructor(string cn, IList<string> args);
+ void RegisterLegacyConstructor(IClassNode c, IList<IConstructorArg> args);
+
+ void BindSetEntry(string iface, string impl);
+ void BindSetEntry(string iface, INode impl);
+ void BindSetEntry(INamedParameterNode iface, string impl);
+ void BindSetEntry(INamedParameterNode iface, INode impl);
+
+ void BindList(string iface, IList<string> impl);
+ void BindList(string iface, IList<INode> impl);
+ void BindList(INamedParameterNode iface, IList<INode> impl);
+ void BindList(INamedParameterNode iface, IList<string> impl);
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-reef/blob/2ae282de/lang/cs/Source/TANG/Tang/Interface/ICsClassHierarchy.cs
----------------------------------------------------------------------
diff --git a/lang/cs/Source/TANG/Tang/Interface/ICsClassHierarchy.cs b/lang/cs/Source/TANG/Tang/Interface/ICsClassHierarchy.cs
new file mode 100644
index 0000000..07c94dc
--- /dev/null
+++ b/lang/cs/Source/TANG/Tang/Interface/ICsClassHierarchy.cs
@@ -0,0 +1,33 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+using System;
+using Org.Apache.Reef.Tang.Types;
+
+namespace Org.Apache.Reef.Tang.Interface
+{
+ public interface ICsClassHierarchy : IClassHierarchy
+ {
+ INode GetNode(Type c);
+ Type ClassForName(string name);
+ object Parse(INamedParameterNode name, string value);
+ object ParseDefaultValue(INamedParameterNode name);
+
+
+ }
+}