http://git-wip-us.apache.org/repos/asf/incubator-reef/blob/2ae282de/lang/cs/Tests/TangTests/SmokeTest/RootImplementation.cs ---------------------------------------------------------------------- diff --git a/lang/cs/Tests/TangTests/SmokeTest/RootImplementation.cs b/lang/cs/Tests/TangTests/SmokeTest/RootImplementation.cs new file mode 100644 index 0000000..4e07e43 --- /dev/null +++ b/lang/cs/Tests/TangTests/SmokeTest/RootImplementation.cs @@ -0,0 +1,178 @@ +/** + * 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.Annotations; + +namespace Org.Apache.Reef.Tang.Test.SmokeTest +{ + public class RootImplementation : IRootInterface + { + private readonly string requiredString; + private readonly string optionalString; + private readonly IAnInterface anInterface; + private readonly int anInt; + private readonly double aDouble; + private readonly InjectableClass injectableClass; + private readonly SetOfImplementations setOfImplementations; + private readonly SetOfBaseTypes setOfBaseTypes; + //private readonly ListOfBaseTypes listOfBaseTypes; //TODO: to recover once Avro NuGet support it + private readonly CyclicDependency cyclicDependency; + + [Inject] + public RootImplementation([Parameter(typeof(TestConfigurationModuleBuilder.RequiredString))] string requiredString, + [Parameter(typeof(TestConfigurationModuleBuilder.OptionalString))] string optionalString, + [Parameter(typeof(TestConfigurationModuleBuilder.NamedParameterInteger))] int anInt, + [Parameter(typeof(TestConfigurationModuleBuilder.NamedParameterDouble))] double aDouble, + IAnInterface anInterface, + InjectableClass injectableClass, + SetOfImplementations setOfImplementations, + SetOfBaseTypes setOfBaseTypes, + //ListOfBaseTypes listOfBaseTypes, //TODO: to recover once Avro NuGet support it + CyclicDependency cyclicDependency) + { + this.requiredString = requiredString; + this.optionalString = optionalString; + this.anInterface = anInterface; + this.anInt = anInt; + this.aDouble = aDouble; + this.injectableClass = injectableClass; + this.setOfImplementations = setOfImplementations; + this.setOfBaseTypes = setOfBaseTypes; + //this.listOfBaseTypes = listOfBaseTypes; //TODO: to recover once Avro NuGet support it + this.cyclicDependency = cyclicDependency; + } + + public bool IsValid() + { + if (!this.setOfImplementations.isValid()) + { + return false; + } + + if (!this.requiredString.Equals(TestConfigurationModuleBuilder.RequiredStringValue)) + { + return false; + } + + if (!this.optionalString.Equals(TestConfigurationModuleBuilder.OptionaStringValue)) + { + return false; + } + + if (this.anInterface == null) + { + return false; + } + + if (this.aDouble != TestConfigurationModuleBuilder.NamedParameterDoubleValue) + { + return false; + } + + if (this.anInt != TestConfigurationModuleBuilder.NamedParameterIntegerValue) + { + return false; + } + + return true; + } + + public override bool Equals(object o) + { + if (this == o) + { + return true; + } + + if (o == null) + { + return false; + } + + RootImplementation that = (RootImplementation)o; + + if (that.aDouble != aDouble) + { + return false; + } + + if (anInt != that.anInt) + { + return false; + } + + if (anInterface != null ? !anInterface.Equals(that.anInterface) : that.anInterface != null) + { + return false; + } + + if (optionalString != null ? !optionalString.Equals(that.optionalString) : that.optionalString != null) + { + return false; + } + + if (requiredString != null ? !requiredString.Equals(that.requiredString) : that.requiredString != null) + { + return false; + } + + if (injectableClass != null ? !injectableClass.Equals(that.injectableClass) : that.injectableClass != null) + { + return false; + } + + if (setOfImplementations != null + ? !setOfImplementations.Equals(that.setOfImplementations) + : that.setOfImplementations != null) + { + return false; + } + + if (setOfBaseTypes != null ? !setOfBaseTypes.Equals(that.setOfBaseTypes) : that.setOfBaseTypes != null) + { + return false; + } + + //TODO: to recover once Avro NuGet support it + //if (listOfBaseTypes != null ? !listOfBaseTypes.Equals(that.listOfBaseTypes) : that.listOfBaseTypes != null) + //{ + // return false; + //} + if (cyclicDependency != null + ? !cyclicDependency.Equals(that.cyclicDependency) + : that.cyclicDependency != null) + { + return false; + } + + return true; + } + + public override int GetHashCode() + { + int result; + result = requiredString != null ? requiredString.GetHashCode() : 0; + result = (31 * result) + (optionalString != null ? optionalString.GetHashCode() : 0); + result = (31 * result) + (anInterface != null ? anInterface.GetHashCode() : 0); + result = (31 * result) + anInt; + result = (31 * result) + aDouble.GetHashCode(); + return result; + } + } +}
http://git-wip-us.apache.org/repos/asf/incubator-reef/blob/2ae282de/lang/cs/Tests/TangTests/SmokeTest/RootInterface.cs ---------------------------------------------------------------------- diff --git a/lang/cs/Tests/TangTests/SmokeTest/RootInterface.cs b/lang/cs/Tests/TangTests/SmokeTest/RootInterface.cs new file mode 100644 index 0000000..fa87f16 --- /dev/null +++ b/lang/cs/Tests/TangTests/SmokeTest/RootInterface.cs @@ -0,0 +1,26 @@ +/** + * 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. + */ + +namespace Org.Apache.Reef.Tang.Test.SmokeTest +{ + public interface IRootInterface + { + bool IsValid(); + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-reef/blob/2ae282de/lang/cs/Tests/TangTests/SmokeTest/RoundTripTest.cs ---------------------------------------------------------------------- diff --git a/lang/cs/Tests/TangTests/SmokeTest/RoundTripTest.cs b/lang/cs/Tests/TangTests/SmokeTest/RoundTripTest.cs new file mode 100644 index 0000000..36ead9c --- /dev/null +++ b/lang/cs/Tests/TangTests/SmokeTest/RoundTripTest.cs @@ -0,0 +1,40 @@ +/** + * 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.Implementations; +using Org.Apache.Reef.Tang.Interface; +using Microsoft.VisualStudio.TestTools.UnitTesting; + +namespace Org.Apache.Reef.Tang.Test.SmokeTest +{ + [TestClass] + public abstract class RoundTripTest + { + public abstract IConfiguration RoundTrip(IConfiguration configuration); + + [TestMethod] + public void TestRoundTrip() + { + IConfiguration conf = ObjectTreeTest.GetConfiguration(); + IRootInterface before = TangFactory.GetTang().NewInjector(conf).GetInstance<IRootInterface>(); + IRootInterface after = TangFactory.GetTang().NewInjector(RoundTrip(conf)).GetInstance<IRootInterface>(); + Assert.AreEqual(before, after, "Configuration conversion to and from Avro datatypes failed."); + } + } +} http://git-wip-us.apache.org/repos/asf/incubator-reef/blob/2ae282de/lang/cs/Tests/TangTests/SmokeTest/SetInterface.cs ---------------------------------------------------------------------- diff --git a/lang/cs/Tests/TangTests/SmokeTest/SetInterface.cs b/lang/cs/Tests/TangTests/SmokeTest/SetInterface.cs new file mode 100644 index 0000000..51cff2c --- /dev/null +++ b/lang/cs/Tests/TangTests/SmokeTest/SetInterface.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; + +namespace Org.Apache.Reef.Tang.Test.SmokeTest +{ + /** + * Interface used for the set injecttion test. + */ + interface ISetInterface : IComparable + { + void AMethod(); + } +} http://git-wip-us.apache.org/repos/asf/incubator-reef/blob/2ae282de/lang/cs/Tests/TangTests/SmokeTest/SetInterfaceImplOne.cs ---------------------------------------------------------------------- diff --git a/lang/cs/Tests/TangTests/SmokeTest/SetInterfaceImplOne.cs b/lang/cs/Tests/TangTests/SmokeTest/SetInterfaceImplOne.cs new file mode 100644 index 0000000..a5c8630 --- /dev/null +++ b/lang/cs/Tests/TangTests/SmokeTest/SetInterfaceImplOne.cs @@ -0,0 +1,82 @@ +/** + * 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.Annotations; + +namespace Org.Apache.Reef.Tang.Test.SmokeTest +{ + public class SetInterfaceImplOne : ISetInterface + { + private readonly int magicNumber; + + [Inject] + public SetInterfaceImplOne() + { + this.magicNumber = 42; + } + + public void AMethod() + { + } + + public override bool Equals(object o) + { + if (this == o) + { + return true; + } + + if (o == null || !(o is SetInterfaceImplOne)) + { + return false; + } + + SetInterfaceImplOne that = (SetInterfaceImplOne)o; + + if (magicNumber != that.magicNumber) + { + return false; + } + + return true; + } + + public override int GetHashCode() + { + return magicNumber; + } + + public int CompareTo(object obj) + { + if (this == obj) + { + return 0; + } + + if (obj == null || !(obj is SetInterfaceImplOne)) + { + return -1; + } + + SetInterfaceImplOne that = (SetInterfaceImplOne)obj; + + return magicNumber.CompareTo(that.magicNumber); + } + } +} http://git-wip-us.apache.org/repos/asf/incubator-reef/blob/2ae282de/lang/cs/Tests/TangTests/SmokeTest/SetInterfaceImplTwo.cs ---------------------------------------------------------------------- diff --git a/lang/cs/Tests/TangTests/SmokeTest/SetInterfaceImplTwo.cs b/lang/cs/Tests/TangTests/SmokeTest/SetInterfaceImplTwo.cs new file mode 100644 index 0000000..859778b --- /dev/null +++ b/lang/cs/Tests/TangTests/SmokeTest/SetInterfaceImplTwo.cs @@ -0,0 +1,82 @@ +/** + * 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.Annotations; + +namespace Org.Apache.Reef.Tang.Test.SmokeTest +{ + public class SetInterfaceImplTwo : ISetInterface + { + private readonly double magicNumber; + + [Inject] + SetInterfaceImplTwo() + { + this.magicNumber = 42.0; + } + + public void AMethod() + { + } + + public override bool Equals(object o) + { + if (this == o) + { + return true; + } + + if (o == null || !(o is SetInterfaceImplTwo)) + { + return false; + } + + SetInterfaceImplTwo that = (SetInterfaceImplTwo)o; + + if (that.magicNumber.CompareTo(magicNumber) != 0) + { + return false; + } + + return true; + } + + public override int GetHashCode() + { + return magicNumber.GetHashCode(); + } + + public int CompareTo(object obj) + { + if (this == obj) + { + return 0; + } + + if (obj == null || !(obj is SetInterfaceImplTwo)) + { + return -1; + } + + SetInterfaceImplTwo that = (SetInterfaceImplTwo)obj; + + return that.magicNumber.CompareTo(magicNumber); + } + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-reef/blob/2ae282de/lang/cs/Tests/TangTests/SmokeTest/SetOfBaseTypes.cs ---------------------------------------------------------------------- diff --git a/lang/cs/Tests/TangTests/SmokeTest/SetOfBaseTypes.cs b/lang/cs/Tests/TangTests/SmokeTest/SetOfBaseTypes.cs new file mode 100644 index 0000000..f2ee763 --- /dev/null +++ b/lang/cs/Tests/TangTests/SmokeTest/SetOfBaseTypes.cs @@ -0,0 +1,105 @@ +/** + * 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.Tang.Annotations; + +namespace Org.Apache.Reef.Tang.Test.SmokeTest +{ + public class SetOfBaseTypes + { + private readonly ISet<int> integers; + private readonly ISet<double> doubles; + private readonly ISet<string> strings; + private readonly ISet<int> moreIntegers; + + [Inject] + private SetOfBaseTypes([Parameter(typeof(Integers))] ISet<int> integers, + [Parameter(typeof(Doubles))] ISet<double> doubles, + [Parameter(typeof(Strings))] ISet<string> strings, + [Parameter(typeof(MoreIntegers))] ISet<int> moreIntegers) + { + this.integers = integers; + this.doubles = doubles; + this.strings = strings; + this.moreIntegers = moreIntegers; + } + + public override bool Equals(object o) + { + if (this == o) + { + return true; + } + + if (o == null || !(o is SetOfBaseTypes)) + { + return false; + } + + SetOfBaseTypes that = (SetOfBaseTypes)o; + + if (!Utilities.Utilities.Equals(doubles, that.doubles)) + { + return false; + } + + if (!Utilities.Utilities.Equals(integers, that.integers)) + { + return false; + } + + if (!Utilities.Utilities.Equals(strings, that.strings)) + { + return false; + } + + return true; + } + + public override int GetHashCode() + { + int result = integers.GetHashCode(); + result = (31 * result) + doubles.GetHashCode(); + result = (31 * result) + strings.GetHashCode(); + return result; + } + + [NamedParameter] + public class Integers : Name<ISet<int>> + { + } + + [NamedParameter(DefaultValues = new string[] { "1", "2", "3" })] + public class MoreIntegers : Name<ISet<int>> + { + } + + [NamedParameter] + public class Doubles : Name<ISet<double>> + { + } + + [NamedParameter] + public class Strings : Name<ISet<string>> + { + } + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-reef/blob/2ae282de/lang/cs/Tests/TangTests/SmokeTest/SetOfImplementations.cs ---------------------------------------------------------------------- diff --git a/lang/cs/Tests/TangTests/SmokeTest/SetOfImplementations.cs b/lang/cs/Tests/TangTests/SmokeTest/SetOfImplementations.cs new file mode 100644 index 0000000..0f75b9a --- /dev/null +++ b/lang/cs/Tests/TangTests/SmokeTest/SetOfImplementations.cs @@ -0,0 +1,72 @@ +/** + * 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 Org.Apache.Reef.Tang.Annotations; + +namespace Org.Apache.Reef.Tang.Test.SmokeTest +{ + public class SetOfImplementations + { + private readonly ISet<ISetInterface> theInstances; + + [Inject] + SetOfImplementations([Parameter(typeof(TestConfigurationModuleBuilder.SetOfInstances))] ISet<ISetInterface> theInstances) + { + this.theInstances = theInstances; + } + + public override bool Equals(object o) + { + if (this == o) + { + return true; + } + + if (o == null || !(o is SetOfImplementations)) + { + return false; + } + + SetOfImplementations that = (SetOfImplementations)o; + + if (that.theInstances.Count != this.theInstances.Count) + { + return false; + } + + if (!Utilities.Utilities.Equals<ISetInterface>(theInstances, that.theInstances)) + { + return false; + } + + return true; + } + + public override int GetHashCode() + { + return theInstances.GetHashCode(); + } + + public bool isValid() + { + return this.theInstances.Count == 2; + } + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-reef/blob/2ae282de/lang/cs/Tests/TangTests/SmokeTest/TestConfigurationModuleBuilder.cs ---------------------------------------------------------------------- diff --git a/lang/cs/Tests/TangTests/SmokeTest/TestConfigurationModuleBuilder.cs b/lang/cs/Tests/TangTests/SmokeTest/TestConfigurationModuleBuilder.cs new file mode 100644 index 0000000..3eaeada --- /dev/null +++ b/lang/cs/Tests/TangTests/SmokeTest/TestConfigurationModuleBuilder.cs @@ -0,0 +1,107 @@ +/** + * 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 Org.Apache.Reef.Tang.Annotations; +using Org.Apache.Reef.Tang.Formats; +using Org.Apache.Reef.Tang.Util; +using Org.Apache.Reef.Tang.Test.Format; + +namespace Org.Apache.Reef.Tang.Test.SmokeTest +{ + class TestConfigurationModuleBuilder : ConfigurationModuleBuilder + { + public static readonly string RequiredStringValue = "Required String Value"; + + public static readonly string OptionaStringValue = "Optional String Value"; + + public static readonly RequiredParameter<string> REQUIREDSTRING = new RequiredParameter<string>(); + + public static readonly OptionalParameter<string> OPTIONALSTRING = new OptionalParameter<string>(); + + public static readonly int NamedParameterIntegerValue = 42; + + public static readonly double NamedParameterDoubleValue = 42.0; + + public static ConfigurationModule CONF + { + get + { + return new TestConfigurationModuleBuilder() + .BindImplementation(GenericType<IRootInterface>.Class, GenericType<RootImplementation>.Class) + .BindNamedParameter<NamedParameterInteger, int>(GenericType<NamedParameterInteger>.Class, NamedParameterIntegerValue.ToString(CultureInfo.CurrentCulture)) + .BindNamedParameter<NamedParameterDouble, double>(GenericType<NamedParameterDouble>.Class, NamedParameterDoubleValue.ToString(CultureInfo.CurrentCulture)) + .BindSetEntry<SetOfInstances, SetInterfaceImplOne, ISetInterface>(GenericType<SetOfInstances>.Class, GenericType<SetInterfaceImplOne>.Class) + .BindSetEntry<SetOfInstances, SetInterfaceImplTwo, ISetInterface>(GenericType<SetOfInstances>.Class, GenericType<SetInterfaceImplTwo>.Class) + .BindNamedParameter(GenericType<RequiredString>.Class, REQUIREDSTRING) + .BindNamedParameter(GenericType<OptionalString>.Class, OPTIONALSTRING) + .BindSetEntry<SetOfBaseTypes.Integers, int>(GenericType<SetOfBaseTypes.Integers>.Class, "1") + .BindSetEntry<SetOfBaseTypes.Integers, int>(GenericType<SetOfBaseTypes.Integers>.Class, "2") + .BindSetEntry<SetOfBaseTypes.Integers, int>(GenericType<SetOfBaseTypes.Integers>.Class, "3") + .BindSetEntry<SetOfBaseTypes.Doubles, double>(GenericType<SetOfBaseTypes.Doubles>.Class, "1") + .BindSetEntry<SetOfBaseTypes.Doubles, double>(GenericType<SetOfBaseTypes.Doubles>.Class, "2") + .BindSetEntry<SetOfBaseTypes.Doubles, double>(GenericType<SetOfBaseTypes.Doubles>.Class, "3") + .BindSetEntry<SetOfBaseTypes.Strings, string>(GenericType<SetOfBaseTypes.Strings>.Class, "1") + .BindSetEntry<SetOfBaseTypes.Strings, string>(GenericType<SetOfBaseTypes.Strings>.Class, "2") + .BindSetEntry<SetOfBaseTypes.Strings, string>(GenericType<SetOfBaseTypes.Strings>.Class, "3") + .BindList<ListOfBaseTypes.Integers, int>(GenericType<ListOfBaseTypes.Integers>.Class, (new List<string>(new string[] { "1", "2", "3" }))) + .BindList<ListOfBaseTypes.Doubles, double>(GenericType<ListOfBaseTypes.Doubles>.Class, (new List<string>(new string[] { "1", "2", "3" }))) + .BindList<ListOfBaseTypes.Strings, string>(GenericType<ListOfBaseTypes.Strings>.Class, (new List<string>(new string[] { "1", "2", "3" }))) + .Build(); + } + } + + [NamedParameter] + public class RequiredString : Name<string> + { + } + + [NamedParameter] + public class SetOfInstances : Name<ISet<ISetInterface>> + { + } + + [NamedParameter()] + public class NamedParameterDouble : Name<double> + { + } + + [NamedParameter()] + public class IntegerHandler : Name<IHandler<int>> + { + } + + [NamedParameter()] + public class StringHandler : Name<IHandler<string>> + { + } + + [NamedParameter()] + public class NamedParameterInteger : Name<int> + { + } + + [NamedParameter(DefaultValue = "default_string_default_value")] + public class OptionalString : Name<string> + { + } + } +} http://git-wip-us.apache.org/repos/asf/incubator-reef/blob/2ae282de/lang/cs/Tests/TangTests/Tang/TestDefaultImpementaion.cs ---------------------------------------------------------------------- diff --git a/lang/cs/Tests/TangTests/Tang/TestDefaultImpementaion.cs b/lang/cs/Tests/TangTests/Tang/TestDefaultImpementaion.cs new file mode 100644 index 0000000..87c37b2 --- /dev/null +++ b/lang/cs/Tests/TangTests/Tang/TestDefaultImpementaion.cs @@ -0,0 +1,196 @@ +/** + * 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.Annotations; +using Org.Apache.Reef.Tang.Exceptions; +using Org.Apache.Reef.Tang.Implementations; +using Org.Apache.Reef.Tang.Interface; +using Org.Apache.Reef.Tang.Util; +using Microsoft.VisualStudio.TestTools.UnitTesting; + +namespace Org.Apache.Reef.Tang.Test.Tang +{ + [DefaultImplementation(Name = "Org.Apache.Reef.Tang.Test.Tang.HaveDefaultStringImplImpl")] + interface IHaveDefaultStringImpl + { + } + + [DefaultImplementation(typeof(HaveDefaultImplImpl))] + interface IHaveDefaultImpl + { + } + + interface IfaceWithDefault + { + } + + [DefaultImplementation(typeof(AnInterfaceImplementation), "default")] + interface IAnInterface + { + void aMethod(); + } + + [TestClass] + public class TestDefaultImplmentation + { + [TestMethod] + public void TestDefaultConstructor() + { + ClassWithDefaultConstructor impl = (ClassWithDefaultConstructor)TangFactory.GetTang().NewInjector().GetInstance(typeof(ClassWithDefaultConstructor)); + Assert.IsNotNull(impl); + } + + [TestMethod] + public void TestDefaultImplementaion() + { + ClassWithDefaultConstructor impl = (ClassWithDefaultConstructor)TangFactory.GetTang().NewInjector().GetInstance(typeof(ClassWithDefaultConstructor)); + Assert.IsNotNull(impl); + } + + [TestMethod] + public void TestDefaultImplOnInterface() + { + IAnInterface impl = (IAnInterface)TangFactory.GetTang().NewInjector().GetInstance(typeof(IAnInterface)); + Assert.IsNotNull(impl); + impl.aMethod(); + } + + [TestMethod] + public void TestGetInstanceOfNamedParameter() + { + IConfigurationBuilder cb = TangFactory.GetTang().NewConfigurationBuilder(); + IInjector i = TangFactory.GetTang().NewInjector(cb.Build()); + IfaceWithDefault iwd = i.GetNamedInstance<IfaceWithDefaultName, IfaceWithDefault>(GenericType<IfaceWithDefaultName>.Class); + Assert.IsNotNull(iwd); + } + + [TestMethod] + public void TestCantGetInstanceOfNamedParameter() + { + string msg = null; + try + { + IConfigurationBuilder cb = TangFactory.GetTang().NewConfigurationBuilder(); + IInjector i = TangFactory.GetTang().NewInjector(cb.Build()); + i.GetInstance<IfaceWithDefaultName>(); + msg = "getInstance() called on Name IfaceWithDefaultName Did you mean to call getNamedInstance() instead?"; + } + catch (InjectionException e) + { + System.Diagnostics.Debug.WriteLine(e); + } + Assert.IsNull(msg); + } + + [TestMethod] + public void TestCanGetDefaultedInterface() + { + Assert.IsNotNull(TangFactory.GetTang().NewInjector().GetInstance<IHaveDefaultImpl>()); + } + + [TestMethod] + public void TestCanOverrideDefaultedInterface() + { + ICsConfigurationBuilder cb = TangFactory.GetTang().NewConfigurationBuilder(); + cb.BindImplementation(GenericType<IHaveDefaultImpl>.Class, GenericType<OverrideDefaultImpl>.Class); + var o = TangFactory.GetTang().NewInjector(cb.Build()).GetInstance<IHaveDefaultImpl>(); + Assert.IsTrue(o is OverrideDefaultImpl); + } + + [TestMethod] + public void TestCanGetStringDefaultedInterface() + { + Assert.IsNotNull(TangFactory.GetTang().NewInjector().GetInstance<IHaveDefaultStringImpl>()); + } + + [TestMethod] + public void TestCanOverrideStringDefaultedInterface() + { + ICsConfigurationBuilder cb = TangFactory.GetTang().NewConfigurationBuilder(); + cb.BindImplementation(GenericType<IHaveDefaultStringImpl>.Class, GenericType<OverrideDefaultStringImpl>.Class); + var o = TangFactory.GetTang().NewInjector(cb.Build()).GetInstance<IHaveDefaultStringImpl>(); + Assert.IsTrue(o is OverrideDefaultStringImpl); + } + } + + public class AnInterfaceImplementation : IAnInterface + { + [Inject] + private AnInterfaceImplementation() + { + } + + public void aMethod() + { + } + } + + class IfaceWithDefaultDefaultImpl : IfaceWithDefault + { + [Inject] + IfaceWithDefaultDefaultImpl() + { + } + } + + [NamedParameter(DefaultClass = typeof(IfaceWithDefaultDefaultImpl))] + class IfaceWithDefaultName : Name<IfaceWithDefault> + { + } + + class HaveDefaultImplImpl : IHaveDefaultImpl + { + [Inject] + HaveDefaultImplImpl() + { + } + } + + class OverrideDefaultImpl : IHaveDefaultImpl + { + [Inject] + public OverrideDefaultImpl() + { + } + } + + class HaveDefaultStringImplImpl : IHaveDefaultStringImpl + { + [Inject] + HaveDefaultStringImplImpl() + { + } + } + + class OverrideDefaultStringImpl : IHaveDefaultStringImpl + { + [Inject] + public OverrideDefaultStringImpl() + { + } + } + + class ClassWithDefaultConstructor + { + [Inject] + public ClassWithDefaultConstructor() + { + } + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-reef/blob/2ae282de/lang/cs/Tests/TangTests/Tang/TestExternalConstructors.cs ---------------------------------------------------------------------- diff --git a/lang/cs/Tests/TangTests/Tang/TestExternalConstructors.cs b/lang/cs/Tests/TangTests/Tang/TestExternalConstructors.cs new file mode 100644 index 0000000..46a60c9 --- /dev/null +++ b/lang/cs/Tests/TangTests/Tang/TestExternalConstructors.cs @@ -0,0 +1,148 @@ +/** + * 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.Annotations; +using Org.Apache.Reef.Tang.Implementations; +using Org.Apache.Reef.Tang.Interface; +using Org.Apache.Reef.Tang.Util; +using Microsoft.VisualStudio.TestTools.UnitTesting; + +namespace Org.Apache.Reef.Tang.Test.Tang +{ + [TestClass] + public class TestExternalConstructors + { + static ITang tang; + + [TestInitialize()] + public void TestSetup() + { + tang = TangFactory.GetTang(); + } + + [TestMethod] + public void TestBindConstructor() + { + ICsConfigurationBuilder b = TangFactory.GetTang().NewConfigurationBuilder(); + b.BindConstructor(GenericType<A>.Class, GenericType<ACons>.Class); + b.BindConstructor(GenericType<B>.Class, GenericType<BCons>.Class); + + TangFactory.GetTang().NewInjector(b.Build()).GetInstance(typeof(B)); + } + + [TestMethod] + public void TestSImpleExternalConstructor() + { + ICsConfigurationBuilder b = TangFactory.GetTang().NewConfigurationBuilder(); + b.BindConstructor(GenericType<A>.Class, GenericType<ACons>.Class); + A aRef = (A)TangFactory.GetTang().NewInjector(b.Build()).GetInstance(typeof(A)); + Assert.IsNotNull(aRef); + } + + [TestMethod] + public void TestExternalLegacyConstructor() + { + ICsConfigurationBuilder cb = tang.NewConfigurationBuilder(); + cb.BindConstructor(GenericType<ExternalConstructorExample.Legacy>.Class, GenericType<ExternalConstructorExample.LegacyWrapper>.Class); + IInjector i = tang.NewInjector(cb.Build()); + i.BindVolatileInstance(GenericType<int>.Class, 42); + i.BindVolatileInstance(GenericType<string>.Class, "The meaning of life is "); + ExternalConstructorExample.Legacy l = i.GetInstance<ExternalConstructorExample.Legacy>(); + Assert.AreEqual(42, l.X); + Assert.AreEqual("The meaning of life is ", l.Y); + } + + public class A + { + public A() + { + } + } + + public class B + { + public B(A a) + { + } + } + + public class ACons : IExternalConstructor<A> + { + [Inject] + ACons() + { + } + + public A NewInstance() + { + return new A(); + } + } + + public class BCons : IExternalConstructor<B> + { + private A a; + [Inject] + BCons(A a) + { + this.a = a; + } + + public B NewInstance() + { + return new B(a); + } + } + } + + class ExternalConstructorExample + { + public class Legacy + { + public Legacy(int x, string y) + { + this.X = x; + this.Y = y; + } + + public int X { get; set; } + + public string Y { get; set; } + } + + public class LegacyWrapper : IExternalConstructor<Legacy> + { + [Inject] + LegacyWrapper(int x, string y) + { + this.X = x; + this.Y = y; + } + + public int X { get; set; } + + public string Y { get; set; } + + public Legacy NewInstance() + { + return new Legacy(X, Y); + } + } + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-reef/blob/2ae282de/lang/cs/Tests/TangTests/Tang/TestLegacyConstructors.cs ---------------------------------------------------------------------- diff --git a/lang/cs/Tests/TangTests/Tang/TestLegacyConstructors.cs b/lang/cs/Tests/TangTests/Tang/TestLegacyConstructors.cs new file mode 100644 index 0000000..49e2609 --- /dev/null +++ b/lang/cs/Tests/TangTests/Tang/TestLegacyConstructors.cs @@ -0,0 +1,73 @@ +/** + * 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.Tang.Implementations; +using Org.Apache.Reef.Tang.Interface; +using Org.Apache.Reef.Tang.Util; +using Microsoft.VisualStudio.TestTools.UnitTesting; + +namespace Org.Apache.Reef.Tang.Test.Tang +{ + [TestClass] + public class TestLegacyConstructors + { + static ITang tang; + + [TestInitialize()] + public void TestSetup() + { + tang = TangFactory.GetTang(); + } + + [TestMethod] + public void TestLegacyConstructor() + { + ICsConfigurationBuilder cb = tang.NewConfigurationBuilder(); + + IList<string> constructorArg = new List<string>(); + constructorArg.Add(ReflectionUtilities.GetAssemblyQualifiedName(typeof(int))); + constructorArg.Add(ReflectionUtilities.GetAssemblyQualifiedName(typeof(string))); + cb.RegisterLegacyConstructor(ReflectionUtilities.GetAssemblyQualifiedName(typeof(LegacyConstructor)), constructorArg); + //cb.Bind(typeof(LegacyConstructor), typeof(LegacyConstructor)); + cb.BindImplementation(GenericType<LegacyConstructor>.Class, GenericType<LegacyConstructor>.Class); + + IInjector i = tang.NewInjector(cb.Build()); + i.BindVolatileInstance(GenericType<int>.Class, 42); + i.BindVolatileInstance(GenericType<string>.Class, "The meaning of life is "); + LegacyConstructor l = i.GetInstance<LegacyConstructor>(); + Assert.AreEqual(42, l.X); + Assert.AreEqual("The meaning of life is ", l.Y); + } + } + + class LegacyConstructor + { + public LegacyConstructor(int x, string y) + { + this.X = x; + this.Y = y; + } + + public int X { get; set; } + + public string Y { get; set; } + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-reef/blob/2ae282de/lang/cs/Tests/TangTests/Tang/TestTang.cs ---------------------------------------------------------------------- diff --git a/lang/cs/Tests/TangTests/Tang/TestTang.cs b/lang/cs/Tests/TangTests/Tang/TestTang.cs new file mode 100644 index 0000000..4ac5158 --- /dev/null +++ b/lang/cs/Tests/TangTests/Tang/TestTang.cs @@ -0,0 +1,1158 @@ +/** + * 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.Reflection; +using Org.Apache.Reef.Tang.Annotations; +using Org.Apache.Reef.Tang.Exceptions; +using Org.Apache.Reef.Tang.Implementations; +using Org.Apache.Reef.Tang.Interface; +using Org.Apache.Reef.Tang.Types; +using Org.Apache.Reef.Tang.Util; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using Org.Apache.Reef.Tang.Examples; + +namespace Org.Apache.Reef.Tang.Test.Tang +{ + [TestClass] + public class TestTang + { + private static ITang tang; + + private static Assembly asm = null; + + [ClassInitialize] + public static void ClassSetup(TestContext context) + { + asm = Assembly.Load(FileNames.Examples); + } + + [ClassCleanup] + public static void ClassCleanup() + { + } + + [TestInitialize()] + public void TestSetup() + { + MustBeSingleton.alreadyInstantiated = false; + tang = TangFactory.GetTang(); + } + + [TestCleanup()] + public void TestCleanup() + { + } + + [TestMethod] + public void TestSingleton() + { + IInjector injector = tang.NewInjector(); + Assert.IsNotNull(injector.GetInstance(typeof (TwoSingletons))); + Assert.IsNotNull(injector.GetInstance(typeof (TwoSingletons))); + } + + [TestMethod] + public void TestNotSingleton() + { + TwoSingletons obj = null; + Assert.IsNotNull(tang.NewInjector().GetInstance(typeof (TwoSingletons))); + try + { + obj = (TwoSingletons) tang.NewInjector().GetInstance(typeof (TwoSingletons)); + } + catch (InjectionException) + { + + } + Assert.IsNull(obj); + } + + [TestMethod] + public void TestRepeatedAmbiguousArgs() + { + INode node = null; + try + { + ICsConfigurationBuilder t = tang.NewConfigurationBuilder(); + node = + t.GetClassHierarchy() + .GetNode(ReflectionUtilities.GetAssemblyQualifiedName(typeof (RepeatedAmbiguousArgs))); + } + catch (ClassHierarchyException) + { + } + Assert.IsNull(node); + } + + [TestMethod] + public void TestRepeatedOKArgs() + { + ICsConfigurationBuilder cb = tang.NewConfigurationBuilder(); + cb.BindNamedParameter<RepeatedNamedArgs.A, Int32>(GenericType<RepeatedNamedArgs.A>.Class, "1"); + cb.BindNamedParameter<RepeatedNamedArgs.B, Int32>(GenericType<RepeatedNamedArgs.B>.Class, "2"); + + IInjector injector = tang.NewInjector(cb.Build()); + injector.GetInstance(typeof (RepeatedNamedArgs)); + } + + // NamedParameter A has no default_value, so this should throw. + [TestMethod] + public void TestOneNamedFailArgs() + { + string msg = null; + try + { + tang.NewInjector().GetInstance<OneNamedSingletonArgs>(); + msg = + "Cannot inject OneNamedSingletonArgs: cOneNamedSingletonArgs missing argument OneNamedSingletonArgs+A"; + } + catch (Exception) + { + } + Assert.IsNull(msg); + } + + // NamedParameter A get's bound to a volatile, so this should succeed. + [TestMethod] + public void TestOneNamedSingletonOKArgs() + { + IInjector i = tang.NewInjector(); + i.BindVolatileParameter(GenericType<OneNamedSingletonArgs.A>.Class, i.GetInstance<MustBeSingleton>()); + OneNamedSingletonArgs o = i.GetInstance<OneNamedSingletonArgs>(); + Assert.IsNotNull(o); + } + + + [TestMethod] + public void TestRepeatedNamedArgs() + { + IInjector i = tang.NewInjector(); + i.BindVolatileParameter(GenericType<RepeatedNamedSingletonArgs.A>.Class, + (MustBeSingleton) i.GetInstance(typeof (MustBeSingleton))); + i.BindVolatileParameter(GenericType<RepeatedNamedSingletonArgs.B>.Class, + (MustBeSingleton) i.GetInstance(typeof (MustBeSingleton))); + i.GetInstance(typeof (RepeatedNamedSingletonArgs)); + } + + [TestMethod] + public void testStraightforwardBuild() + { + ICsConfigurationBuilder cb = tang.NewConfigurationBuilder(); + cb.BindImplementation(GenericType<Interf>.Class, GenericType<Impl>.Class); + tang.NewInjector(cb.Build()).GetInstance(typeof (Interf)); + } + + [TestMethod] + public void TestOneNamedStringArgCantRebind() + { + ICsConfigurationBuilder cb = tang.NewConfigurationBuilder(); + OneNamedStringArg a = + (OneNamedStringArg) tang.NewInjector(cb.Build()).GetInstance(typeof (OneNamedStringArg)); + Assert.AreEqual("default", a.s); + cb.BindNamedParameter<OneNamedStringArg.A, string>(GenericType<OneNamedStringArg.A>.Class, "not default"); + IInjector i = tang.NewInjector(cb.Build()); + Assert.AreEqual("not default", ((OneNamedStringArg) i.GetInstance(typeof (OneNamedStringArg))).s); + string msg = null; + try + { + i.BindVolatileParameter(GenericType<OneNamedStringArg.A>.Class, "volatile"); + msg = + "Attempt to re-bind named parameter Org.Apache.Reef.Tang.OneNamedStringArg$A. Old value was [not default] new value is [volatile]"; + } + catch (Exception) + { + } + Assert.IsNull(msg); + } + + [TestMethod] + public void TestOneNamedStringArgBind() + { + ICsConfigurationBuilder cb = tang.NewConfigurationBuilder(); + OneNamedStringArg a = tang.NewInjector(cb.Build()).GetInstance<OneNamedStringArg>(); + Assert.AreEqual("default", a.s); + cb.BindNamedParameter<OneNamedStringArg.A, string>(GenericType<OneNamedStringArg.A>.Class, "not default"); + IInjector i = tang.NewInjector(cb.Build()); + Assert.AreEqual("not default", i.GetInstance<OneNamedStringArg>().s); + } + + [TestMethod] + public void TestOneNamedStringArgVolatile() + { + OneNamedStringArg a = tang.NewInjector().GetInstance<OneNamedStringArg>(); + Assert.AreEqual("default", a.s); + IInjector i = tang.NewInjector(); + i.BindVolatileParameter(GenericType<OneNamedStringArg.A>.Class, "volatile"); + Assert.AreEqual("volatile", i.GetInstance<OneNamedStringArg>().s); + } + + [TestMethod] + public void TestTwoNamedStringArgsBind() + { + ICsConfigurationBuilder cb = tang.NewConfigurationBuilder(); + TwoNamedStringArgs a = tang.NewInjector(cb.Build()).GetInstance<TwoNamedStringArgs>(); + Assert.AreEqual("defaultA", a.a); + Assert.AreEqual("defaultB", a.b); + cb.BindNamedParameter<TwoNamedStringArgs.A, string>(GenericType<TwoNamedStringArgs.A>.Class, "not defaultA"); + cb.BindNamedParameter<TwoNamedStringArgs.B, string>(GenericType<TwoNamedStringArgs.B>.Class, "not defaultB"); + IInjector i = tang.NewInjector(cb.Build()); + Assert.AreEqual("not defaultA", + i.GetInstance<TwoNamedStringArgs>().a); + Assert.AreEqual("not defaultB", + i.GetInstance<TwoNamedStringArgs>().b); + } + + [TestMethod] + public void TestTwoNamedStringArgsBindVolatile() + { + ICsConfigurationBuilder cb = tang.NewConfigurationBuilder(); + TwoNamedStringArgs a = tang.NewInjector(cb.Build()).GetInstance<TwoNamedStringArgs>(); + Assert.AreEqual("defaultA", a.a); + Assert.AreEqual("defaultB", a.b); + IInjector i = tang.NewInjector(cb.Build()); + i.BindVolatileParameter(GenericType<TwoNamedStringArgs.A>.Class, "not defaultA"); + i.BindVolatileParameter(GenericType<TwoNamedStringArgs.B>.Class, "not defaultB"); + Assert.AreEqual("not defaultA", + i.GetInstance<TwoNamedStringArgs>().a); + Assert.AreEqual("not defaultB", + i.GetInstance<TwoNamedStringArgs>().b); + } + + [TestMethod] + public void TestTwoNamedStringArgsReBindVolatileFail() + { + ICsConfigurationBuilder cb = tang.NewConfigurationBuilder(); + TwoNamedStringArgs a = tang.NewInjector(cb.Build()).GetInstance<TwoNamedStringArgs>(); + Assert.AreEqual("defaultA", a.a); + Assert.AreEqual("defaultB", a.b); + cb.BindNamedParameter<TwoNamedStringArgs.A, string>(GenericType<TwoNamedStringArgs.A>.Class, "not defaultA"); + cb.BindNamedParameter<TwoNamedStringArgs.B, string>(GenericType<TwoNamedStringArgs.B>.Class, "not defaultB"); + IInjector i = tang.NewInjector(cb.Build()); + string msg = null; + try + { + i.BindVolatileParameter(GenericType<TwoNamedStringArgs.A>.Class, "not defaultA"); + i.BindVolatileParameter(GenericType<TwoNamedStringArgs.B>.Class, "not defaultB"); + msg = + "Attempt to re-bind named parameter TwoNamedStringArgs+A. Old value was [not defaultA] new value is [not defaultA]"; + } + catch (Exception) + { + } + Assert.IsNull(msg); + } + + [TestMethod] + public void TestBextendsAinjectA() + { + ICsConfigurationBuilder cb = tang.NewConfigurationBuilder(); + cb.BindImplementation(GenericType<BextendsAinjectA.A>.Class, GenericType<BextendsAinjectA.A>.Class); + BextendsAinjectA.A a = tang.NewInjector(cb.Build()).GetInstance<BextendsAinjectA.A>(); + Assert.IsNotNull(a); + } + + [TestMethod] + public void TestNamedImpl() + { + ICsConfigurationBuilder cb = TangFactory.GetTang().NewConfigurationBuilder(new string[] { FileNames.Examples }); + cb.BindNamedParameter<AImplName, Aimpl, INamedImplA>(GenericType<AImplName>.Class, GenericType<Aimpl>.Class); + cb.BindNamedParameter<BImplName, Bimpl, INamedImplA>(GenericType<BImplName>.Class, GenericType<Bimpl>.Class); + + IInjector i = TangFactory.GetTang().NewInjector(cb.Build()); + Aimpl a1 = (Aimpl) i.GetNamedInstance<AImplName, INamedImplA>(GenericType<AImplName>.Class); + Aimpl a2 = (Aimpl) i.GetNamedInstance<AImplName, INamedImplA>(GenericType<AImplName>.Class); + Bimpl b1 = (Bimpl) i.GetNamedInstance<BImplName, INamedImplA>(GenericType<BImplName>.Class); + Bimpl b2 = (Bimpl) i.GetNamedInstance<BImplName, INamedImplA>(GenericType<BImplName>.Class); + Assert.AreSame(a1, a2); + Assert.AreSame(b1, b2); + } + + [TestMethod] + public void testThreeConstructors() + { + ICsConfigurationBuilder cb = tang.NewConfigurationBuilder(); + cb.BindNamedParameter<ThreeConstructors.TCInt, Int32>(GenericType<ThreeConstructors.TCInt>.Class, "1"); + cb.BindNamedParameter<ThreeConstructors.TCString, string>(GenericType<ThreeConstructors.TCString>.Class, "s"); + ThreeConstructors tc = tang.NewInjector(cb.Build()).GetInstance<ThreeConstructors>(); + Assert.AreEqual(1, tc.i); + Assert.AreEqual("s", tc.s); + + cb = tang.NewConfigurationBuilder(); + cb.BindNamedParameter<ThreeConstructors.TCInt, Int32>(GenericType<ThreeConstructors.TCInt>.Class, "1"); + tc = tang.NewInjector(cb.Build()).GetInstance<ThreeConstructors>(); + Assert.AreEqual(1, tc.i); + Assert.AreEqual("default", tc.s); + + cb = tang.NewConfigurationBuilder(); + cb.BindNamedParameter<ThreeConstructors.TCString, string>(GenericType<ThreeConstructors.TCString>.Class, "s"); + tc = tang.NewInjector(cb.Build()).GetInstance<ThreeConstructors>(); + Assert.AreEqual(-1, tc.i); + Assert.AreEqual("s", tc.s); + + cb = tang.NewConfigurationBuilder(); + cb.BindNamedParameter<ThreeConstructors.TCFloat, float>(GenericType<ThreeConstructors.TCFloat>.Class, "2"); + tc = tang.NewInjector(cb.Build()).GetInstance<ThreeConstructors>(); + Assert.AreEqual(-1, tc.i); + Assert.AreEqual("default", tc.s); + Assert.AreEqual(2.0f, tc.f, 1e-9); + } + + [TestMethod] + public void TestThreeConstructorsAmbiguous() + { + string msg = null; + + try + { + ICsConfigurationBuilder cb = tang.NewConfigurationBuilder(); + cb.BindNamedParameter<ThreeConstructors.TCString, string>(GenericType<ThreeConstructors.TCString>.Class, "s"); + cb.BindNamedParameter<ThreeConstructors.TCFloat, float>(GenericType<ThreeConstructors.TCFloat>.Class, "-2"); + + // Ambiguous; there is a constructor that takes a string, and another that + // takes a float, but none that takes both. + tang.NewInjector(cb.Build()).GetInstance<ThreeConstructors>(); + msg = @"Cannot inject Org.Apache.Reef.Tang.Test.Tang.ThreeConstructors, Org.Apache.Reef.Tang.Test, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null " + + "Ambiguous subplan Org.Apache.Reef.Tang.Test.Tang.ThreeConstructors, Org.Apache.Reef.Tang.Test, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null " + + "new Org.Apache.Reef.Tang.Test.Tang.ThreeConstructors(System.String Org.Apache.Reef.Tang.Test.Tang.ThreeConstructors+TCString = s) " + + "new Org.Apache.Reef.Tang.Test.Tang.ThreeConstructors(System.Single Org.Apache.Reef.Tang.Test.Tang.ThreeConstructors+TCFloat = -2) "; + } + catch (InjectionException e) + { + System.Diagnostics.Debug.WriteLine(e); + } + Assert.IsNull(msg); + } + + [TestMethod] + public void TestTwoConstructorsAmbiguous() + { + string msg = null; + try + { + ICsConfigurationBuilder cb = tang.NewConfigurationBuilder(); + cb.BindNamedParameter<TwoConstructors.TCInt, Int32>(GenericType<TwoConstructors.TCInt>.Class, "1"); + cb.BindNamedParameter<ThreeConstructors.TCString, string>(GenericType<ThreeConstructors.TCString>.Class, "s"); + tang.NewInjector(cb.Build()).GetInstance<TwoConstructors>(); + msg = @"Cannot inject Org.Apache.Reef.Tang.Test.Tang.TwoConstructors, Org.Apache.Reef.Tang.Test, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null "+ + "Ambiguous subplan Org.Apache.Reef.Tang.Test.Tang.TwoConstructors, Org.Apache.Reef.Tang.Test, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" + + "new Org.Apache.Reef.Tang.Test.Tang.TwoConstructors(System.Int32 Org.Apache.Reef.Tang.Test.Tang.TwoConstructors+TCInt = 1, System.String Org.Apache.Reef.Tang.Test.Tang.TwoConstructors+TCString = s)" + + "new Org.Apache.Reef.Tang.Test.Tang.TwoConstructors(System.String Org.Apache.Reef.Tang.Test.Tang.TwoConstructors+TCString = s, System.Int32 Org.Apache.Reef.Tang.Test.Tang.TwoConstructors+TCInt = 1)"; + } + catch (InjectionException e) + { + System.Diagnostics.Debug.WriteLine(e); + } + Assert.IsNull(msg); + } + + [TestMethod] + public void TestSingletonWithMultipleConstructors() + { + ICsConfigurationBuilder cb = TangFactory.GetTang().NewConfigurationBuilder(); + cb.BindImplementation(GenericType<SMC>.Class, GenericType<SingletonMultiConst>.Class); + cb.BindNamedParameter<SingletonMultiConst.A, string>(GenericType<SingletonMultiConst.A>.Class, "foo"); + IInjector i = TangFactory.GetTang().NewInjector(cb.Build()); + var o = i.GetInstance<SMC>(); + Assert.IsNotNull(o); + } + + [TestMethod] + public void TestSingletonWithMoreSpecificConstructors() + { + ICsConfigurationBuilder cb = TangFactory.GetTang().NewConfigurationBuilder(); + cb.BindImplementation(GenericType<SMC>.Class, GenericType<SingletonMultiConst>.Class); + cb.BindNamedParameter<SingletonMultiConst.A, string>(GenericType<SingletonMultiConst.A>.Class, "foo"); + cb.BindNamedParameter<SingletonMultiConst.B, string>(GenericType<SingletonMultiConst.B>.Class, "bar"); + IInjector i = TangFactory.GetTang().NewInjector(cb.Build()); + var o = i.GetInstance<SMC>(); + Assert.IsNotNull(o); + } + + [TestMethod] + public void TestInjectInjector() + { + IInjector i = TangFactory.GetTang().NewInjector(); + var ii = (InjectInjector) i.GetInstance(typeof(InjectInjector)); + //Assert.IsTrue(ii.i is IInjector); + Assert.AreNotSame(i, ii.i); + } + + [TestMethod] + public void TestGenericEventHandlers() + { + ICsConfigurationBuilder cba = TangFactory.GetTang().NewConfigurationBuilder(); + cba.BindNamedParameter<ABCName.XName, ABCName.XXBB, ABCName.X<ABCName.BB>>(GenericType<ABCName.XName>.Class, GenericType<ABCName.XXBB>.Class); + TangFactory.GetTang().NewInjector(cba.Build()).GetNamedInstance(typeof(ABCName.XName)); + + ICsConfigurationBuilder cbb = TangFactory.GetTang().NewConfigurationBuilder(); + cbb.BindNamedParameter<ABCName.XName, ABCName.XBB, ABCName.X<ABCName.BB>>(GenericType<ABCName.XName>.Class, GenericType<ABCName.XBB>.Class); + TangFactory.GetTang().NewInjector(cbb.Build()).GetNamedInstance(typeof(ABCName.XName)); + } + + [TestMethod] + public void TestGenericEventHandlerDefaults() + { + ICsConfigurationBuilder cba = TangFactory.GetTang().NewConfigurationBuilder(); + var xbb = TangFactory.GetTang().NewInjector(cba.Build()).GetNamedInstance(typeof(ABCName.XNameDB)); + Assert.IsTrue(xbb is ABCName.XBB); + } + + [TestMethod] + public void TestGenericEventHandlerDefaultsGoodTreeIndirection() + { + ICsConfigurationBuilder cba = TangFactory.GetTang().NewConfigurationBuilder(); + var o = TangFactory.GetTang().NewInjector(cba.Build()).GetNamedInstance(typeof(ABCName.XNameDDAA)); + Assert.IsTrue(o is ABCName.XXBB); + } + + [TestMethod] + public void TestGenericUnrelatedGenericTypeParameters() + { + string msg = null; + try + { + ICsConfigurationBuilder cba = TangFactory.GetTang().NewConfigurationBuilder(); + TangFactory.GetTang().NewInjector(cba.Build()).GetNamedInstance(typeof(WaterBottleName)); + msg = + "class WaterBottleName defines a default class GasCan with a type that does not extend its target's type Water"; + } + catch (ClassHierarchyException e) + { + System.Diagnostics.Debug.WriteLine(e); + } + Assert.IsNull(msg); + } + + [TestMethod] + public void TestGenericInterfaceUnboundTypeParametersName() + { + ICsConfigurationBuilder cba = TangFactory.GetTang().NewConfigurationBuilder(); + var o = TangFactory.GetTang().NewInjector(cba.Build()).GetNamedInstance(typeof(FooEventHandler)); + Assert.IsTrue(o is MyEventHandler<Foo>); + } + + [TestMethod] + public void TestGenericInterfaceUnboundTypeParametersNameIface() + { + ICsConfigurationBuilder cba = TangFactory.GetTang().NewConfigurationBuilder(); + var o = TangFactory.GetTang().NewInjector(cba.Build()).GetNamedInstance(typeof(IfaceEventHandler)); + Assert.IsTrue(o is IEventHandler<SomeIface>); + } + + [TestMethod] + public void TestGenericInterfaceUnboundTypeParametersIface() + { + string msg = null; + try + { + ICsConfigurationBuilder cba = TangFactory.GetTang().NewConfigurationBuilder(); + TangFactory.GetTang().NewInjector(cba.Build()).IsInjectable(typeof(MyEventHandlerIface)); + msg = + "interface MyEventHandlerIface declares its default implementation to be non-subclass class MyEventHandler"; + } + catch (ClassHierarchyException e) + { + System.Diagnostics.Debug.WriteLine(e); + } + Assert.IsNull(msg); + } + + [TestMethod] + public void TestWantSomeHandlers() + { + var o = TangFactory.GetTang().NewInjector().GetInstance<WantSomeHandlers>(); + Assert.IsNotNull(o); + } + + [TestMethod] + public void TestWantSomeHandlersBadOrder() + { + IInjector i = TangFactory.GetTang().NewInjector(); + var o1 = i.GetInstance<IAHandler>(); + var o2 = i.GetInstance<IBHandler>(); + var o3 = i.GetInstance<WantSomeFutureHandlers>(); + Assert.IsTrue(o1 is AHandlerImpl); + Assert.IsTrue(o2 is BHandlerImpl); + Assert.IsNotNull(o3); + } + + [TestMethod] + public void TestWantSomeFutureHandlersAlreadyBoundVolatile() + { + IInjector i = TangFactory.GetTang().NewInjector(); + i.BindVolatileInstance(GenericType<IAHandler>.Class, new AHandlerImpl()); + i.BindVolatileInstance(GenericType<IBHandler>.Class, new BHandlerImpl()); + i.GetInstance<WantSomeFutureHandlers>(); + } + + [TestMethod] + public void TestWantSomeFutureHandlers() + { + TangFactory.GetTang().NewInjector().GetInstance<WantSomeFutureHandlers>(); + } + + [TestMethod] + public void TestWantSomeFutureHandlersName() + { + TangFactory.GetTang().NewInjector().GetInstance<WantSomeFutureHandlersName>(); + } + + [TestMethod] + public void TestReuseFailedInjector() + { + IInjector i = TangFactory.GetTang().NewInjector(); + try + { + i.GetInstance<Fail>(); + Assert.Fail("Injecting Fail should not have worked!"); + } catch (InjectionException) + { + i.GetInstance<Pass>(); + } + } + + [TestMethod] + public void TestMultipleLayersFromAbstractClass() + { + ICsConfigurationBuilder cb = tang.NewConfigurationBuilder(); + cb.BindImplementation(GenericType<MultiLayer>.Class, GenericType<LowerLayer>.Class); + MultiLayer o = tang.NewInjector(cb.Build()).GetInstance<MultiLayer>(); + Assert.IsNotNull(o); + } + + [TestMethod] + public void TestMultipleLayersFromInterface() + { + ICsConfigurationBuilder cb = tang.NewConfigurationBuilder(); + cb.BindImplementation(GenericType<IMultiLayer>.Class, GenericType<LowerLayerImpl>.Class); + IMultiLayer o = tang.NewInjector(cb.Build()).GetInstance<IMultiLayer>(); + Assert.IsNotNull(o); + } + } + + internal class InjectInjector + { + public IInjector i; + + [Inject] + private InjectInjector(IInjector i) + { + this.i = i; + } + } + + internal class MustBeSingleton + { + public static bool alreadyInstantiated; + + [Inject] + public MustBeSingleton() + { + if (alreadyInstantiated) + { + throw new IllegalStateException("Can't instantiate me twice!"); + } + alreadyInstantiated = true; + } + } + + internal class SubSingleton + { + [Inject] + private SubSingleton(MustBeSingleton a) + { + // Does not call super + } + } + + internal class TwoSingletons + { + [Inject] + private TwoSingletons(SubSingleton a, MustBeSingleton b) + { + } + } + + internal class RepeatedAmbiguousArgs + { + [Inject] + private RepeatedAmbiguousArgs(int x, int y) + { + } + } + + public class RepeatedNamedArgs + { + [NamedParameter] + public class A : Name<Int32> + { + } + + [NamedParameter()] + public class B : Name<Int32> + { + } + + [Inject] + public RepeatedNamedArgs([Parameter(typeof (A))] int x, [Parameter(Value = typeof (B))] int y) + { + } + } + + internal class RepeatedNamedSingletonArgs + { + [NamedParameter()] + public class A : Name<MustBeSingleton> + { + } + + [NamedParameter()] + public class B : Name<MustBeSingleton> + { + } + + [Inject] + public RepeatedNamedSingletonArgs([Parameter(typeof (A))] MustBeSingleton a, + [Parameter(typeof (B))] MustBeSingleton b) + { + } + } + + internal class OneNamedSingletonArgs + { + [NamedParameter()] + public class A : Name<MustBeSingleton> + { + } + + [NamedParameter()] + public class B : Name<MustBeSingleton> + { + } + + [Inject] + public OneNamedSingletonArgs([Parameter(typeof (A))] MustBeSingleton a) + { + } + } + + [NamedParameter(Documentation = "woo", ShortName = "woo", DefaultValue = "42")] + internal class Param : Name<Int32> + { + } + + internal interface Interf + { + } + + internal class Impl : Interf + { + [Inject] + private Impl([Parameter(Value = typeof (Param))] int p) + { + } + } + + internal class OneNamedStringArg + { + [NamedParameter(DefaultValue = "default")] + public class A : Name<string> + { + } + + public string s; + + [Inject] + private OneNamedStringArg([Parameter(typeof (A))] string s) + { + this.s = s; + } + } + + internal class TwoNamedStringArgs + { + [NamedParameter(DefaultValue = "defaultA")] + public class A : Name<string> + { + } + + [NamedParameter(DefaultValue = "defaultB")] + public class B : Name<string> + { + } + + public string a; + public string b; + + [Inject] + private TwoNamedStringArgs([Parameter(typeof (A))] string a, [Parameter(typeof (B))] String b) + { + this.a = a; + this.b = b; + } + } + + internal class BextendsAinjectA + { + public class A + { + [Inject] + public A() + { + } + } + + public class B : A + { + } + } + + public interface INamedImplA + { + } + + public interface INamedImplC + { + } + + [NamedParameter] + public class AImplName : Name<INamedImplA> + { + } + + [NamedParameter] + public class BImplName : Name<INamedImplA> + { + } + + [NamedParameter] + public class CImplName : Name<INamedImplC> + { + } + + public class Aimpl : INamedImplA + { + [Inject] + private Aimpl() + { + } + } + + public class Bimpl : INamedImplA + { + [Inject] + private Bimpl() + { + } + } + + public class Cimpl : INamedImplC + { + [Inject] + private Cimpl() + { + } + } + + internal class NamedImpl + { + [NamedParameter] + public class AImplName : Name<A> + { + } + + [NamedParameter] + public class BImplName : Name<A> + { + } + + [NamedParameter] + public class CImplName : Name<C> + { + } + + public interface A + { + } + + public interface C + { + } + + public class Aimpl : A + { + [Inject] + private Aimpl() + { + } + } + + public class Bimpl : A + { + [Inject] + private Bimpl() + { + } + } + + public class Cimpl : C + { + [Inject] + private Cimpl() + { + } + } + + public class ABtaker + { + [Inject] + private ABtaker([Parameter(typeof (AImplName))] INamedImplA a, [Parameter(typeof (BImplName))] INamedImplA b) + { + //Assert.IsTrue(a is Aimpl, "AImplName must be instance of Aimpl"); + //Assert.IsTrue(b is Bimpl, "BImplName must be instance of Bimpl"); + } + } + } + + class ThreeConstructors + { + public int i; + public string s; + public float f; + + [NamedParameter] + public class TCInt : Name<Int32> {} + + [NamedParameter] + public class TCString : Name<string> { } + + [NamedParameter] + public class TCFloat : Name<float> {} + + [Inject] + public ThreeConstructors([Parameter(typeof(TCInt))] int i, [Parameter(typeof(TCString))] string s) + { + this.i = i; + this.s = s; + this.f = -1.0f; + } + + [Inject] + public ThreeConstructors([Parameter(typeof(TCString))] string s) : this(-1, s) + { + } + + [Inject] + public ThreeConstructors([Parameter(typeof(TCInt))] int i) : this(i, "default") + { + } + + [Inject] + public ThreeConstructors([Parameter(typeof(TCFloat))] float f) + { + this.i = -1; + this.s = "default"; + this.f = f; + } + } + + class TwoConstructors + { + public int i; + public string s; + + [NamedParameter] + public class TCInt : Name<Int32> { } + + [NamedParameter] + public class TCString : Name<string> { } + + + [Inject] + public TwoConstructors([Parameter(typeof(TCInt))] int i, [Parameter(typeof(TCString))] string s) + { + this.i = i; + this.s = s; + } + + [Inject] + public TwoConstructors([Parameter(typeof(TCString))] string s, [Parameter(typeof(TCInt))] int i) + { + this.i = i; + this.s = s; + } + } + + interface SMC { } + + class SingletonMultiConst : SMC + { + [NamedParameter] + public class A : Name<string> { } + + [NamedParameter] + public class B : Name<string> { } + + [Inject] + public SingletonMultiConst([Parameter(typeof(A))] String a) { } + + [Inject] + public SingletonMultiConst([Parameter(typeof(A))] string a, [Parameter(typeof(B))] string b) { } + } + + internal class ABCName + { + public interface X<T> + { + } + + [NamedParameter] + public class XName : Name<X<BB>> + { + } + + //[NamedParameter(DefaultClass = typeof(XAA))] + //public class XNameDA : Name<X<BB>> + //{ + //} + + [NamedParameter(DefaultClass = typeof(XBB))] + public class XNameDB : Name<X<BB>> + { + } + + //[NamedParameter(DefaultClass = typeof(XCC))] + //public class XNameDC : Name<X<BB>> + //{ + //} + + //[NamedParameter(DefaultClass = typeof(XCC))] + //public class XNameDAA : Name<XBB> + //{ + //} + + [NamedParameter(DefaultClass = typeof(XXBB))] + public class XNameDDAA : Name<XBB> + { + } + + [DefaultImplementation(typeof(AA))] + public class AA + { + [Inject] + public AA() + { + } + } + + [DefaultImplementation(typeof(BB))] + public class BB : AA + { + [Inject] + public BB() + { + } + } + + [DefaultImplementation(typeof(CC))] + public class CC : BB + { + [Inject] + public CC() + { + } + } + + public class XAA : X<AA> + { + [Inject] + public XAA(AA aa) + { + } + } + + [DefaultImplementation(typeof(XBB))] + public class XBB : X<BB> + { + [Inject] + public XBB(BB aa) + { + } + } + + public class XXBB : XBB + { + [Inject] + public XXBB(BB aa) + : base(aa) + { + } + } + + public class XCC : X<CC> + { + [Inject] + public XCC(CC aa) + { + } + } + } + + interface Bottle<Y> { + + } + class WaterBottle : Bottle<Water> + { + } + class GasCan : Bottle<Gas> + { + } + class Water {} + class Gas {} + + [NamedParameter(DefaultClass=typeof(GasCan))] + class WaterBottleName : Name<Bottle<Water>> { } + + interface IEventHandler <T> { } + class MyEventHandler<T> : IEventHandler<T> + { + [Inject] + MyEventHandler () { } + } + + [DefaultImplementation(typeof(MyEventHandler<Foo>))] + interface MyEventHandlerIface : IEventHandler<Foo> { } + + [NamedParameter(DefaultClass = typeof(MyEventHandler<Foo>))] + class FooEventHandler : Name<IEventHandler<Foo>> { } + + internal class Foo : Name<String> + { + } + + interface SomeIface { } + [NamedParameter(DefaultClass = typeof(MyEventHandler<SomeIface>))] + class IfaceEventHandler : Name<IEventHandler<SomeIface>> { } + + class AH + { + [Inject] + AH() {} + } + class BH + { + [Inject] + BH() {} + } + + [DefaultImplementation(typeof(AHandlerImpl))] + interface IAHandler : IEventHandler<AH> { } + + [DefaultImplementation(typeof(BHandlerImpl))] + interface IBHandler : IEventHandler<BH> { } + + class AHandlerImpl : IAHandler + { + [Inject] + public AHandlerImpl() { } + } + class BHandlerImpl : IBHandler + { + [Inject] + public BHandlerImpl() { } + } + + class WantSomeHandlers + { + [Inject] + WantSomeHandlers(IAHandler a, IBHandler b) { } + } + class WantSomeFutureHandlers + { + [Inject] + WantSomeFutureHandlers(IInjectionFuture<IAHandler> a, IInjectionFuture<IBHandler> b) { } + } + + [NamedParameter(DefaultClass = typeof(AHandlerImpl))] + class AHandlerName : Name<IEventHandler<AH>> { } + + [NamedParameter(DefaultClass = typeof(BHandlerImpl))] + class BHandlerName : Name<IEventHandler<BH>> { } + + class WantSomeFutureHandlersName + { + [Inject] + WantSomeFutureHandlersName( + [Parameter(typeof (AHandlerName))] IInjectionFuture<IEventHandler<AH>> a, + [Parameter(typeof (BHandlerName))] IInjectionFuture<IEventHandler<BH>> b) + { + } + } + + class Pass + { + [Inject] + public Pass() + { + } + } + + class Fail + { + [Inject] + public Fail() + { + throw new NotSupportedException(); + } + } + + abstract class MultiLayer + { + + } + + class MiddleLayer : MultiLayer + { + [Inject] + public MiddleLayer() { } + } + + class LowerLayer : MiddleLayer + { + [Inject] + public LowerLayer() { } + } + + interface IMultiLayer + { + + } + + class MiddleLayerImpl : IMultiLayer + { + [Inject] + public MiddleLayerImpl() { } + } + + class LowerLayerImpl : MiddleLayerImpl + { + [Inject] + public LowerLayerImpl() { } + } +} \ No newline at end of file
