public void ShouldSupportTwoRegistrations() { ITargetContainer targets = new TargetContainer(); var simpleType = new NoCtor(); ITarget target1 = Target.ForObject("hello world"); ITarget target2 = Target.ForObject(new NoCtor()); targets.Register(target1); targets.Register(target2); Assert.Same(target1, targets.Fetch(typeof(string))); Assert.Same(target2, targets.Fetch(typeof(NoCtor))); }
public void Projection_ShouldProject_FromRegistration() { // This time, projecting to an interface for which we have one registration // Demonstrates that the container will use a specific registration instead // of auto-binding the implementation type. // Arrange var targets = new TargetContainer(); targets.RegisterType <From1>(); targets.RegisterType <From2>(); var expectedTarget = Target.ForType <To>(); targets.Register(expectedTarget, typeof(ITo)); targets.RegisterProjection <From, ITo>(); // Act var result = targets.Fetch(typeof(IEnumerable <ITo>)); // Assert var enumTarget = Assert.IsType <EnumerableTarget>(result); Assert.Collection(enumTarget, new Action <ITarget>[] { t => { var projTarget = Assert.IsType <ProjectionTarget>(t); Assert.Same(expectedTarget, projTarget.OutputTarget); Assert.Equal(typeof(From1), projTarget.InputTarget.DeclaredType); }, t => { var projTarget = Assert.IsType <ProjectionTarget>(t); Assert.Same(expectedTarget, projTarget.OutputTarget); Assert.Equal(typeof(From2), projTarget.InputTarget.DeclaredType); } }); }
public void ShouldNotRegisterIfTypesDontMatch() { ITarget t = new ObjectTarget("hello world"); ITargetContainer r = new TargetContainer(); Assert.Throws <ArgumentException>(() => r.Register(t, serviceType: typeof(int))); }
public void ShouldFavourSpecialisationOfGenericInt() { // Arrange ITargetContainer targets = new TargetContainer(); var notExpected = Target.ForType(typeof(Generic <>)); var expected = Target.ForType(typeof(AltGeneric <int>)); targets.Register(notExpected, typeof(IGeneric <>)); targets.Register(expected, typeof(IGeneric <int>)); // Act var fetched = targets.Fetch(typeof(IGeneric <int>)); // Assert Assert.NotSame(notExpected, fetched); Assert.Same(expected, fetched); }
public void Covariant_Enumerable_ShouldContainAllMatches_NestedCovariant() { // Arrange var targets = new TargetContainer(); var baseTarget = Target.ForType <Covariant <BaseClass> >(); var childTarget = Target.ForType <Covariant <BaseClassChild> >(); var grandChildTarget = Target.ForType <Covariant <BaseClassGrandchild> >(); targets.Register(baseTarget, typeof(ICovariant <BaseClass>)); targets.Register(childTarget, typeof(ICovariant <BaseClassChild>)); targets.Register(grandChildTarget, typeof(ICovariant <BaseClassGrandchild>)); // Act var enumerableTarget = Assert.IsType <EnumerableTarget>(targets.Fetch(typeof(IEnumerable <ICovariant <BaseClass> >))); // Assert Assert.Equal(new[] { baseTarget.Id, childTarget.Id, grandChildTarget.Id }, enumerableTarget.Targets.Select(t => t.Id)); }
public void Covariant_ShouldNotRetrieveConstrained() { // Arrange var targets = new TargetContainer(); var expected = Target.ForType(typeof(Covariant <>)); var notExpected = Target.ForType(typeof(ConstrainedCovariant <>)); targets.Register(expected, typeof(ICovariant <>)); targets.Register(notExpected, typeof(ICovariant <>)); // Act var single = targets.Fetch(typeof(ICovariant <string>)); var all = targets.FetchAll(typeof(ICovariant <string>)); // Assert Assert.Same(expected, single); Assert.Single(all, expected); }
public void ShouldNotFetchConstrainedGenericForIncompatibleType() { // Arrange ITargetContainer targets = new TargetContainer(); var expected = Target.ForType(typeof(Generic <>)); var notexpected = Target.ForType(typeof(ConstrainedGeneric <>)); targets.Register(expected, typeof(IGeneric <>)); targets.Register(notexpected, typeof(IGeneric <>)); // Act var single = targets.Fetch(typeof(IGeneric <string>)); var all = targets.FetchAll(typeof(IGeneric <string>)); // Assert Assert.Same(expected, single); Assert.Single(all, expected); }
public void ShouldRegisterForImplicitType() { ITarget t = new ObjectTarget("hello word"); ITargetContainer rezolverBuilder = new TargetContainer(); rezolverBuilder.Register(t); var t2 = rezolverBuilder.Fetch(typeof(string)); Assert.Same(t, t2); }
public void Covariant_Enumerable_ShouldContainAllMatches() { // Arrange var targets = new TargetContainer(); var baseTarget = Target.ForType <BaseClass>(); var childTarget = Target.ForType <BaseClassChild>(); var grandChildTarget = Target.ForType <BaseClassGrandchild>(); targets.Register(baseTarget); targets.Register(childTarget); targets.Register(grandChildTarget); // Act var enumerableTarget = Assert.IsType <EnumerableTarget>(targets.Fetch(typeof(IEnumerable <BaseClass>))); // Assert // (can't compare targets because Assert.Equal(new[] { typeof(BaseClass), typeof(BaseClassChild), typeof(BaseClassGrandchild) }, enumerableTarget.Targets.Select(t => t.DeclaredType)); }
public void WillRejectBecauseIncompatibleType() { // <example3> var targets = new TargetContainer(); // int is obviously not compatible with IMyService. Assert.Throws <ArgumentException>( () => targets.Register(Target.ForObject(50), typeof(IMyService))); // </example3> }
public void Covariant_Enumerable_ShouldContainOneMatchBecauseOptionDisablesEnumerableCovariance() { // Arrange var targets = new TargetContainer(); targets.SetOption <Options.EnableEnumerableCovariance>(false); var baseTarget = Target.ForType <BaseClass>(); var childTarget = Target.ForType <BaseClassChild>(); var grandChildTarget = Target.ForType <BaseClassGrandchild>(); targets.Register(baseTarget); targets.Register(childTarget); targets.Register(grandChildTarget); // Act var enumerableTarget = Assert.IsType <EnumerableTarget>(targets.Fetch(typeof(IEnumerable <BaseClass>))); // Assert Assert.Equal(new[] { baseTarget }, enumerableTarget.Targets); }
public void ShouldInheritParentRegistration() { var parent = new TargetContainer(); var overriding = new OverridingTargetContainer(parent); var parentTarget = new TestTarget(typeof(int), useFallBack: false, supportsType: true); parent.Register(parentTarget); Assert.Same(parentTarget, overriding.Fetch(typeof(int))); }
public void Covariant_ShouldFetchNestedCovariant_CovariantIndexBug() { // As part of the work done to solve stack overflows when covariance is enabled and // a type is registered which implements a generic interface or inherits a generic // base into which it passes itself; I then introduced a bug whereby covariant compatibility // detection would depend on the order in which types were registered in the target container. // This test specifically verifies that that erroneous behaviour has not regressed. // Arrange var targets = new TargetContainer(); var grandChildTarget = Target.ForType <BaseClassGrandchild>(); var nestedgrandChildTarget = Target.ForType <Covariant <BaseClassGrandchild> >(); targets.Register(grandChildTarget); targets.Register(nestedgrandChildTarget, typeof(ICovariant <BaseClassGrandchild>)); //Act var match = targets.Fetch(typeof(ICovariant <BaseClass>)); Assert.Equal(nestedgrandChildTarget.Id, match.Id); }
public void ShouldFavourGenericSpecialisationOfGeneric() { // Arrange ITargetContainer targets = new TargetContainer(); var target = Target.ForType(typeof(Generic <>)); //note here - using MakeGenericType is the only way to get a reference to a type like IFoo<IFoo<>> because //supply an open generic as a type parameter to a generic is not valid. var target2 = Target.ForType(typeof(NestedGenericA <>)); targets.Register(target, typeof(IGeneric <>)); targets.Register(target2, typeof(IGeneric <>).MakeGenericType(typeof(IEnumerable <>))); // Act var fetched = targets.Fetch(typeof(IGeneric <IEnumerable <int> >)); var fetched2 = targets.Fetch(typeof(IGeneric <int>)); // Assert Assert.Same(target2, fetched); Assert.Same(target, fetched2); }
public void ShouldRegisterNullObjectTarget() { // <example1> ITarget t = new ObjectTarget(null); ITargetContainer r = new TargetContainer(); r.Register(t, serviceType: typeof(object)); var t2 = r.Fetch(typeof(object)); Assert.Same(t, t2); // </example1> }
public void LookupByBase() { // <example2> var targets = new TargetContainer(); targets.Register(Target.ForType <MyService>(), typeof(IMyService)); var target = targets.Fetch(typeof(IMyService)); Assert.IsType <ConstructorTarget>(target); // </example2> }
public void Covariant_Enumerable_ShouldContainOneMatchBecauseOptionDisablesEnumerableCovarianceForThatEnumerable() { // Arrange var targets = new TargetContainer(); targets.SetOption <Options.EnableEnumerableCovariance, BaseClass>(false); var baseTarget = Target.ForType <BaseClass>(); var childTarget = Target.ForType <BaseClassChild>(); var grandChildTarget = Target.ForType <BaseClassGrandchild>(); var nestedbaseTarget = Target.ForType <Covariant <BaseClass> >(); var nestedchildTarget = Target.ForType <Covariant <BaseClassChild> >(); var nestedgrandChildTarget = Target.ForType <Covariant <BaseClassGrandchild> >(); targets.Register(baseTarget); targets.Register(childTarget); targets.Register(grandChildTarget); targets.Register(nestedbaseTarget, typeof(ICovariant <BaseClass>)); targets.Register(nestedchildTarget, typeof(ICovariant <BaseClassChild>)); targets.Register(nestedgrandChildTarget, typeof(ICovariant <BaseClassGrandchild>)); // Act var enumerableTarget = Assert.IsType <EnumerableTarget>(targets.Fetch(typeof(IEnumerable <BaseClass>))); var nestedEnumerableTarget = Assert.IsType <EnumerableTarget>(targets.Fetch(typeof(IEnumerable <ICovariant <BaseClass> >))); // Assert Assert.Equal(new[] { baseTarget.Id }, enumerableTarget.Targets.Select(t => t.Id)); Assert.Equal(new[] { nestedbaseTarget.Id, nestedchildTarget.Id, nestedgrandChildTarget.Id }, nestedEnumerableTarget.Targets.Select(t => t.Id)); }
public void MixedVariance_ShouldFetchCompatibleFunc() { // Arrange var targets = new TargetContainer(); var expected = Target.ForObject(new Func <object, string>(o => o.ToString())); targets.Register(expected); // Act var result = targets.Fetch(typeof(Func <string, object>)); // Assert Assert.Equal(expected.Id, result.Id); }
public void ShouldSupportRegisteringAndRetrievingGenericWithGenericParameter() { // Arrange ITargetContainer targets = new TargetContainer(); var target = Target.ForType(typeof(Generic <>)); targets.Register(target, typeof(IGeneric <>)); // Act var fetched = targets.Fetch(typeof(IGeneric <IGeneric <int> >)); // Assert Assert.Same(target, fetched); }
public void Covariant_ShouldFetch(string name, Type tTarget, Type toFetch) { // Arrange ITargetContainer targets = new TargetContainer(); var target = new TestTarget(tTarget, false, true, ScopeBehaviour.None); targets.Register(target); // Act var fetched = targets.Fetch(toFetch); // Assert Assert.Equal(target.Id, fetched.Id); }
public void ShouldSupportRegisteringAndRetrievingGenericWithAsymmetricGenericBase() { // Arrange ITargetContainer targets = new TargetContainer(); var target = Target.ForType(typeof(NestedGenericA <>)); targets.Register(target, typeof(IGeneric <>).MakeGenericType(typeof(IEnumerable <>))); // Act var fetched = targets.Fetch(typeof(IGeneric <IEnumerable <int> >)); // Assert Assert.Same(target, fetched); }
public void ShouldFetchConstrainedGenericInsteadOfOpen() { // registration order matters, for now, when registering constrained generics // because they are registered against the open generic type. Therefore, if // an unconstrained open generic is registered *after* one with constraints, then // that will win for any single-service Fetch. // Arrange ITargetContainer targets = new TargetContainer(); var openTarget = Target.ForType(typeof(Generic <>)); var constrainedTarget = Target.ForType(typeof(ConstrainedGeneric <>)); targets.Register(openTarget, typeof(IGeneric <>)); targets.Register(constrainedTarget, typeof(IGeneric <>)); // Act var fetched = targets.Fetch(typeof(IGeneric <BaseClassChild>)); // this should return both as they both apply var all = targets.FetchAll(typeof(IGeneric <BaseClassChild>)); // Assert Assert.Same(constrainedTarget, fetched); Assert.Equal(new[] { openTarget, constrainedTarget }, all); }
public void ShouldSupportRegisteringOpenGenericAndFetchingAsClosed() { // Arrange ITargetContainer targets = new TargetContainer(); var target = Target.ForType(typeof(Generic <>)); targets.Register(target, typeof(IGeneric <>)); // Act var fetched = targets.Fetch(typeof(IGeneric <>)); var fetchedClosed = targets.Fetch(typeof(IGeneric <int>)); // Assert Assert.Same(target, fetched); Assert.Same(target, fetchedClosed); }
public void EnumerableTargetShouldReturnAllItems() { var parent = new TargetContainer(); var overriding = new OverridingTargetContainer(parent); var parentTarget = new TestTarget(typeof(int), useFallBack: false, supportsType: true); parent.Register(parentTarget); var overrideTarget = new TestTarget(typeof(int), useFallBack: false, supportsType: true); overriding.Register(overrideTarget); var fetched = Assert.IsType <EnumerableTarget>(overriding.Fetch(typeof(IEnumerable <int>))); Assert.Equal(2, fetched.Targets.Count()); }
public void Covariant_ShouldBeCorrectForFuncObjectDelegate() { // Arrange var targets = new TargetContainer(); var funcTarget = Target.ForObject(new Func <string>(() => "Hello World")); // <-- expected behaviour is that the presence of this registration // will cause the Func<string> to be included in the search list. targets.Register(funcTarget); // Act var result = new TargetTypeSelector(typeof(Func <object>), targets).ToArray(); LogActual(result); // Assert Assert.Equal(new[] { typeof(Func <object>), typeof(Func <string>), typeof(Func <>) }, result); }
public void FetchAllShouldReturnAllTargets() { var parent = new TargetContainer(); var overriding = new OverridingTargetContainer(parent); var parentTarget = new TestTarget(typeof(int), useFallBack: false, supportsType: true); parent.Register(parentTarget); var overrideTarget = new TestTarget(typeof(int), useFallBack: false, supportsType: true); overriding.Register(overrideTarget); var fetched = overriding.FetchAll(typeof(int)).ToArray(); Assert.Equal(2, fetched.Length); Assert.Same(parentTarget, fetched[0]); Assert.Same(overrideTarget, fetched[1]); }
public void ShouldFetchContravariant(Type tTarget, Type toFetch) { // this theory specifically tests that if we register a target for a generic which // has contravariant type parameters, then it will be found automatically. // the actual handling of creating an instance is tested in the compiler spec tests // covering the ConstructorTarget // Arrange ITargetContainer targets = new TargetContainer(); var target = new TestTarget(tTarget, false, true, ScopeBehaviour.None); targets.Register(target); // Act var fetched = targets.Fetch(toFetch); // Assert Assert.Equal(target.Id, fetched.Id); }
public void Covariant_ShouldBeCorrectForFuncIEnumerableCharDelegate() { // Arrange var targets = new TargetContainer(); var funcTarget = Target.ForObject(new Func <string>(() => "Hello World")); targets.Register(funcTarget); // Act var result = new TargetTypeSelector(typeof(Func <IEnumerable <char> >), targets).ToArray(); LogActual(result); // Assert Assert.Equal(new[] { typeof(Func <IEnumerable <char> >), typeof(Func <string>), typeof(Func <>).MakeGenericType(typeof(IEnumerable <>)), typeof(Func <>) }, result); }
public void ShouldReceiveNotificationOfTargetAdded() { // Arrange IRootTargetContainer targetContainer = new TargetContainer(); List <(IRootTargetContainer, Events.TargetRegisteredEventArgs)> allEvents = new List <(IRootTargetContainer, TargetRegisteredEventArgs)>(); targetContainer.TargetRegistered += (o, e) => { allEvents.Add((o as IRootTargetContainer, e)); }; // Act var target = Target.ForObject(1); targetContainer.Register(target); // Assert Assert.NotEmpty(allEvents); var lastEvent = allEvents[allEvents.Count - 1]; Assert.Same(targetContainer, lastEvent.Item1); Assert.Same(target, lastEvent.Item2.Target); Assert.Equal(typeof(int), lastEvent.Item2.Type); }
private static void RegisterTwoTargets(TargetContainer targets, Type type) { targets.Register(new TestTarget(type, false, true)); targets.Register(new TestTarget(type, false, true)); }