public void GlobalSetup() { var ninjectSettings = new NinjectSettings { LoadExtensions = false }; var kernelConfiguration = new KernelConfiguration(ninjectSettings); kernelConfiguration.Bind <IWarrior>().To <SpecialNinja>().WhenInjectedExactlyInto <NinjaBarracks>(); kernelConfiguration.Bind <IWarrior>().To <Samurai>().WhenInjectedExactlyInto <Barracks>(); kernelConfiguration.Bind <IWarrior>().To <FootSoldier>().WhenInjectedExactlyInto <Barracks>(); kernelConfiguration.Bind <IWeapon>().To <Shuriken>().WhenInjectedExactlyInto <Barracks>(); kernelConfiguration.Bind <IWeapon>().To <ShortSword>().WhenInjectedExactlyInto <Spartan>(); _injectorFactory = new ExpressionInjectorFactory(); _contextWithParams = CreateContext(kernelConfiguration, kernelConfiguration.BuildReadOnlyKernel(), new List <IParameter> { new ConstructorArgument("height", 34), new PropertyValue("name", "cutter"), new ConstructorArgument("width", 17), new ConstructorArgument("location", "Biutiful") }, typeof(StandardConstructorScorerBenchmark), ninjectSettings); _contextWithoutParams = CreateContext(kernelConfiguration, kernelConfiguration.BuildReadOnlyKernel(), Enumerable.Empty <IParameter>(), typeof(StandardConstructorScorerBenchmark), ninjectSettings); _injectCtor = typeof(NinjaBarracks).GetConstructor(new[] { typeof(IWarrior), typeof(IWeapon) }); _injectCtorDirective = new ConstructorInjectionDirective(_injectCtor, _injectorFactory.Create(_injectCtor)); _defaultCtor = typeof(NinjaBarracks).GetConstructor(new Type[0]); _defaultCtorDirective = new ConstructorInjectionDirective(_defaultCtor, _injectorFactory.Create(_defaultCtor)); _knifeCtor = typeof(Knife).GetConstructor(new[] { typeof(int), typeof(int) }); _knifeCtorDirective = new ConstructorInjectionDirective(_knifeCtor, _injectorFactory.Create(_knifeCtor)); _knifeDefaultsCtor = typeof(Knife).GetConstructor(new[] { typeof(bool), typeof(string) }); _knifeDefaultsCtorDirective = new ConstructorInjectionDirective(_knifeDefaultsCtor, _injectorFactory.Create(_knifeDefaultsCtor)); _spartanNameAndAgeCtor = typeof(Spartan).GetConstructor(new[] { typeof(string), typeof(int) }); _spartanNameAndAgeCtorDirective = new ConstructorInjectionDirective(_spartanNameAndAgeCtor, _injectorFactory.Create(_spartanNameAndAgeCtor)); _spartanHeightAndWeaponCtor = typeof(Spartan).GetConstructor(new[] { typeof(string), typeof(int) }); _spartanHeightAndWeaponCtorDirective = new ConstructorInjectionDirective(_spartanHeightAndWeaponCtor, _injectorFactory.Create(_spartanHeightAndWeaponCtor)); _barracksCtor = typeof(Barracks).GetConstructor(new[] { typeof(IWarrior), typeof(IWeapon) }); _barracksCtorDirective = new ConstructorInjectionDirective(_barracksCtor, _injectorFactory.Create(_barracksCtor)); _monasteryCtor = typeof(Monastery).GetConstructor(new[] { typeof(IWarrior), typeof(IWeapon) }); _monasteryCtorDirective = new ConstructorInjectionDirective(_monasteryCtor, _injectorFactory.Create(_monasteryCtor)); _standardConstructorScorer = new StandardConstructorScorer(ninjectSettings); }
/*----------------------------------------------------------------------------------------*/ #region Public Methods /// <summary> /// Creates an injection directive for the specified constructor. /// </summary> /// <param name="binding">The binding.</param> /// <param name="constructor">The constructor to create the directive for.</param> /// <returns>The created directive.</returns> public ConstructorInjectionDirective Create(IBinding binding, ConstructorInfo constructor) { var directive = new ConstructorInjectionDirective(constructor); CreateArgumentsForMethod(binding, constructor).Each(directive.Arguments.Add); return directive; }
/// <summary> /// Gets the score for the specified constructor. /// </summary> /// <param name="context">The injection context.</param> /// <param name="directive">The constructor.</param> /// <returns>The constructor's score.</returns> public virtual int Score(IContext context, ConstructorInjectionDirective directive) { Ensure.ArgumentNotNull(context, "context"); Ensure.ArgumentNotNull(directive, "constructor"); if (directive.HasInjectAttribute) { return(int.MaxValue); } var score = 1; foreach (ITarget target in directive.Targets) { if (ParameterExists(context, target)) { score++; continue; } if (BindingExists(context, target)) { score++; continue; } score++; if (score > 0) { score += int.MinValue; } } return(score); }
public void Create_ShouldUseConstructorArgumentsForBestConstructor() { var seq = new MockSequence(); var injectorOneMock = new Mock <ConstructorInjector>(MockBehavior.Strict); var injectorTwoMock = new Mock <ConstructorInjector>(MockBehavior.Strict); var directiveOne = new ConstructorInjectionDirective(GetMyServiceWeaponAndWarriorConstructor(), injectorOneMock.Object); var directiveTwo = new ConstructorInjectionDirective(GetMyServiceClericAndName(), injectorTwoMock.Object); var name = new Random().Next().ToString(); var cleric = new Monk(); var instance = new object(); var parameters = new List <IParameter> { new ConstructorArgument("name", name), new ConstructorArgument("weapon", new Dagger()), new ConstructorArgument("cleric", cleric), }; var kernelConfiguration = new KernelConfiguration(_ninjectSettings); var context = CreateContext(kernelConfiguration, kernelConfiguration.BuildReadOnlyKernel(), parameters, typeof(NinjaBarracks), _providerCallbackMock.Object, _ninjectSettings); context.Plan = new Plan(typeof(MyService)); context.Plan.Add(directiveOne); context.Plan.Add(directiveTwo); _constructorScorerMock.InSequence(seq).Setup(p => p.Score(context, directiveOne)).Returns(2); _constructorScorerMock.InSequence(seq).Setup(p => p.Score(context, directiveTwo)).Returns(3); injectorTwoMock.InSequence(seq).Setup(p => p(cleric, name)).Returns(instance); var actual = _standardProvider.Create(context); Assert.Same(instance, actual); }
/// <summary> /// Gets the score for the specified constructor. /// </summary> /// <param name="context">The injection context.</param> /// <param name="directive">The constructor.</param> /// <returns>The constructor's score.</returns> public virtual int Score(IContext context, ConstructorInjectionDirective directive) { Contract.Requires(context != null); Contract.Requires(directive != null); if (directive.HasInjectAttribute) { return int.MaxValue; } var score = 1; foreach (ITarget target in directive.Targets) { if (this.ParameterExists(context, target)) { score++; continue; } if (this.BindingExists(context, target)) { score++; continue; } score++; if (score > 0) { score += int.MinValue; } } return score; }
/// <summary> /// Gets the score for the specified constructor. /// </summary> /// <param name="context">The injection context.</param> /// <param name="directive">The constructor.</param> /// <returns>The constructor's score.</returns> public virtual int Score(IContext context, ConstructorInjectionDirective directive) { Ensure.ArgumentNotNull(context, "context"); Ensure.ArgumentNotNull(directive, "constructor"); if (directive.HasInjectAttribute) { return int.MaxValue; } var score = 1; foreach (ITarget target in directive.Targets) { if (ParameterExists(context, target)) { score++; continue; } if (BindingExists(context, target)) { score++; continue; } score++; if (score > 0) { score += int.MinValue; } } return score; }
/// <summary> /// Gets the score for the specified constructor. /// </summary> /// <param name="context">The injection context.</param> /// <param name="directive">The constructor.</param> /// <returns>The constructor's score.</returns> public virtual int Score(IContext context, ConstructorInjectionDirective directive) { Contract.Requires(context != null); Contract.Requires(directive != null); if (directive.HasInjectAttribute) { return(int.MaxValue); } var score = 1; foreach (ITarget target in directive.Targets) { if (this.ParameterExists(context, target)) { score++; continue; } if (this.BindingExists(context, target)) { score++; continue; } score++; if (score > 0) { score += int.MinValue; } } return(score); }
/// <summary> /// Gets the score for the specified constructor. /// </summary> /// <param name="context">The injection context.</param> /// <param name="directive">The constructor.</param> /// <returns>The constructor's score.</returns> public int Score(IContext context, ConstructorInjectionDirective directive) { Ensure.ArgumentNotNull(context, "context"); Ensure.ArgumentNotNull(directive, "constructor"); if(directive.Constructor.HasAttribute(Settings.InjectAttribute)) return Int32.MaxValue; int score = 1; foreach(ITarget target in directive.Targets) { foreach(IParameter parameter in context.Parameters) { if(string.Equals(target.Name, parameter.Name)) { score++; continue; } } Type targetType = target.Type; if(targetType.IsArray) targetType = targetType.GetElementType(); if(targetType.IsGenericType && targetType.GetInterfaces().Any(type => type == typeof(IEnumerable))) targetType = targetType.GetGenericArguments()[0]; if(context.Kernel.GetBindings(targetType).Count() > 0) score++; } return score; }
/*----------------------------------------------------------------------------------------*/ #region Public Methods /// <summary> /// Creates an injection directive for the specified constructor. /// </summary> /// <param name="binding">The binding.</param> /// <param name="constructor">The constructor to create the directive for.</param> /// <returns>The created directive.</returns> public ConstructorInjectionDirective Create(IBinding binding, ConstructorInfo constructor) { var directive = new ConstructorInjectionDirective(constructor); CreateArgumentsForMethod(binding, constructor).Each(directive.Arguments.Add); return(directive); }
public void TwoArguments() { var directive = new ConstructorInjectionDirective(_twoArgumentConstructor, _twoArgumentIinjector); if (directive == null) { throw new Exception(); } }
/// <summary> /// Gets the score for the specified constructor. Looks at the number of "resolvable" arguments. /// </summary> /// <param name="context">The injection context.</param> /// <param name="directive">The constructor.</param> /// <returns>The constructor's score.</returns> public int Score(IContext context, ConstructorInjectionDirective directive) { if (directive.Constructor.HasAttribute(Settings.InjectAttribute)) return Int32.MaxValue; var bindableParameters = from param in directive.Constructor.GetParameters() where !param.IsOut && !param.IsRetval && !param.IsOptional && param.ParameterType.IsBindable(context.Kernel) select param; return bindableParameters.Count(); }
public PlanTests() { _constructor1 = CreateConstructorInjectionDirective(); _constructor2 = CreateConstructorInjectionDirective(); _property = CreatePropertyInjectionDirective(); _plan = new Plan(this.GetType()); _plan.Add(_constructor1); _plan.Add(_property); _plan.Add(_constructor2); }
/// <summary> /// Adds a serial of <see cref="ConstructorInjectionDirective"/>s to the plan for the constructors /// that could be injected. /// </summary> /// <param name="plan">The plan that is being generated.</param> /// <exception cref="ArgumentNullException"><paramref name="plan"/> is <see langword="null"/>.</exception> public void Execute(IPlan plan) { Ensure.ArgumentNotNull(plan, nameof(plan)); var constructors = this.selector.SelectConstructorsForInjection(plan.Type); foreach (var constructor in constructors) { var directive = new ConstructorInjectionDirective(constructor, this.injectorFactory.Create(constructor)); plan.Add(directive); } }
public override int Score(IContext context, ConstructorInjectionDirective directive) { //has more than one constructor //and the constructor being considered is parameterless if (directive.Constructor.GetType().GetConstructors().Count() > 1 && !directive.Targets.Any()) { //give it a low score return(Int32.MinValue); } return(base.Score(context, directive)); }
/// <summary> /// Gets the score for the specified constructor. Looks at the number of "resolvable" arguments. /// </summary> /// <param name="context">The injection context.</param> /// <param name="directive">The constructor.</param> /// <returns>The constructor's score.</returns> public int Score(IContext context, ConstructorInjectionDirective directive) { if (directive.Constructor.HasAttribute(Settings.InjectAttribute)) { return(Int32.MaxValue); } var bindableParameters = from param in directive.Constructor.GetParameters() where !param.IsOut && !param.IsRetval && !param.IsOptional && param.ParameterType.IsBindable(context.Kernel) select param; return(bindableParameters.Count()); }
/*----------------------------------------------------------------------------------------*/ /// <summary> /// Executed to build the activation plan. /// </summary> /// <param name="binding">The binding that points at the type whose activation plan is being released.</param> /// <param name="type">The type whose activation plan is being manipulated.</param> /// <param name="plan">The activation plan that is being manipulated.</param> /// <returns> /// A value indicating whether to proceed or interrupt the strategy chain. /// </returns> public override StrategyResult Build(IBinding binding, Type type, IActivationPlan plan) { // Get the list of candidate constructors. ConstructorInfo[] candidates = type.GetConstructors(Kernel.Options.GetBindingFlags()); ConstructorInfo injectionConstructor = binding.Components.MemberSelector.SelectConstructor(binding, plan, candidates); // If an injection constructor was found, create an injection directive for it. if (injectionConstructor != null) { ConstructorInjectionDirective directive = binding.Components.DirectiveFactory.Create(binding, injectionConstructor); plan.Directives.Add(directive); } return(StrategyResult.Proceed); }
/// <summary> /// Gets the score for the specified constructor. /// </summary> /// <param name="context">The injection context.</param> /// <param name="directive">The constructor.</param> /// <returns>The constructor's score.</returns> public int Score(IContext context, ConstructorInjectionDirective directive) { Ensure.ArgumentNotNull(context, "context"); Ensure.ArgumentNotNull(directive, "constructor"); if (directive.Constructor.HasAttribute(Settings.InjectAttribute)) { return(Int32.MaxValue); } int score = 1; foreach (ITarget target in directive.Targets) { if (ParameterExists(context, target)) { score++; continue; } Type targetType = target.Type; if (targetType.IsArray) { targetType = targetType.GetElementType(); } if (targetType.IsGenericType && targetType.GetInterfaces().Any(type => type == typeof(IEnumerable))) { targetType = targetType.GetGenericArguments()[0]; } if (context.Kernel.GetBindings(targetType).Any()) { score++; } else { score++; if (score > 0) { score += Int32.MinValue; } } } return(score); }
public void Create_ShouldThrowInvalidOperationExceptionWhenNoConstructorArgumentIsAvailableForGivenParameterAndResolveReturnsMultipleResults() { var seq = new MockSequence(); var injectorOneMock = new Mock <ConstructorInjector>(MockBehavior.Strict); var injectorTwoMock = new Mock <ConstructorInjector>(MockBehavior.Strict); var directiveOne = new ConstructorInjectionDirective(GetMyServiceWeaponAndWarriorConstructor(), injectorOneMock.Object); var directiveTwo = new ConstructorInjectionDirective(GetMyServiceClericAndName(), injectorTwoMock.Object); var readOnlyKernelMock = new Mock <IReadOnlyKernel>(MockBehavior.Strict); var childRequestMock = new Mock <IRequest>(MockBehavior.Strict); var planMock = new Mock <IPlan>(MockBehavior.Strict); var instance = new object(); var weaponMock = new Mock <IWeapon>(MockBehavior.Strict); var warriorMock = new Mock <IWarrior>(MockBehavior.Strict); var directives = new[] { directiveOne, directiveTwo }; var parameters = new List <IParameter> { new ConstructorArgument("name", "Foo"), new ConstructorArgument("weapon", weaponMock.Object), new ConstructorArgument("cleric", new Monk()), }; _contextMock.InSequence(seq).Setup(p => p.Plan).Returns(_planMock.Object); _contextMock.InSequence(seq).Setup(p => p.Plan).Returns(_planMock.Object); _planMock.InSequence(seq).Setup(p => p.GetAll <ConstructorInjectionDirective>()).Returns(directives); _constructorScorerMock.InSequence(seq).Setup(p => p.Score(_contextMock.Object, directiveOne)).Returns(3); _constructorScorerMock.InSequence(seq).Setup(p => p.Score(_contextMock.Object, directiveTwo)).Returns(2); _contextMock.InSequence(seq).Setup(p => p.Parameters).Returns(parameters); _contextMock.InSequence(seq).Setup(p => p.Parameters).Returns(parameters); _contextMock.InSequence(seq).Setup(p => p.Request).Returns(_requestMock.Object); _requestMock.InSequence(seq).Setup(p => p.CreateChild(typeof(IWarrior), _contextMock.Object, It.IsAny <ParameterTarget>())).Returns(childRequestMock.Object); childRequestMock.InSequence(seq).SetupSet(p => p.IsUnique = true); _contextMock.InSequence(seq).Setup(p => p.Kernel).Returns(readOnlyKernelMock.Object); readOnlyKernelMock.InSequence(seq).Setup(p => p.Resolve(childRequestMock.Object)).Returns(new[] { warriorMock.Object, new FootSoldier() }); var actualException = Assert.Throws <InvalidOperationException>(() => _standardProvider.Create(_contextMock.Object)); Assert.Null(actualException.InnerException); Assert.Equal("Sequence contains more than one element", actualException.Message); }
/// <summary> /// Gets the score for the specified constructor. /// </summary> /// <param name="context">The injection context.</param> /// <param name="directive">The constructor.</param> /// <returns>The constructor's score.</returns> public int Score(IContext context, ConstructorInjectionDirective directive) { Ensure.ArgumentNotNull(context, "context"); Ensure.ArgumentNotNull(directive, "constructor"); if(directive.Constructor.HasAttribute(Settings.InjectAttribute)) return Int32.MaxValue; int score = 1; foreach(ITarget target in directive.Targets) { if(context.Kernel.GetBindings(target.Type).Count() > 0) { score++; } } return score; }
/// <summary> /// Adds a <see cref="ConstructorInjectionDirective"/> to the plan for the constructor /// that should be injected. /// </summary> /// <param name="plan">The plan that is being generated.</param> public void Execute(IPlan plan) { IEnumerable<ConstructorInfo> constructors = Selector.SelectConstructorsForInjection(plan.Type); if(constructors == null) return; foreach(ConstructorInfo constructor in constructors) { var hasInjectAttribute = constructor.HasAttribute(Settings.InjectAttribute); var directive = new ConstructorInjectionDirective(constructor, InjectorFactory.Create(constructor)) { HasInjectAttribute = hasInjectAttribute }; plan.Add(directive); } }
public void Create_ShouldPassResolvedObjectForGivenParameterWhenNoConstructorArgumentIsAvailableForParameterAndResolveReturnsSingleResult() { var seq = new MockSequence(); var injectorOneMock = new Mock <ConstructorInjector>(MockBehavior.Strict); var injectorTwoMock = new Mock <ConstructorInjector>(MockBehavior.Strict); var directiveOne = new ConstructorInjectionDirective(GetMyServiceWeaponAndWarriorConstructor(), injectorOneMock.Object); var directiveTwo = new ConstructorInjectionDirective(GetMyServiceClericAndName(), injectorTwoMock.Object); var weaponMock = new Mock <IWeapon>(MockBehavior.Strict); var warriorMock = new Mock <IWarrior>(MockBehavior.Strict); var readOnlyKernelMock = new Mock <IReadOnlyKernel>(MockBehavior.Strict); var childRequestMock = new Mock <IRequest>(MockBehavior.Strict); var planMock = new Mock <IPlan>(MockBehavior.Strict); var expected = new object(); var directives = new[] { directiveOne, directiveTwo }; var parameters = new List <IParameter> { new ConstructorArgument("name", "Foo"), new ConstructorArgument("weapon", weaponMock.Object), new ConstructorArgument("cleric", new Monk()), }; _contextMock.InSequence(seq).Setup(p => p.Plan).Returns(_planMock.Object); _contextMock.InSequence(seq).Setup(p => p.Plan).Returns(_planMock.Object); _planMock.InSequence(seq).Setup(p => p.GetAll <ConstructorInjectionDirective>()).Returns(directives); _constructorScorerMock.InSequence(seq).Setup(p => p.Score(_contextMock.Object, directiveOne)).Returns(3); _constructorScorerMock.InSequence(seq).Setup(p => p.Score(_contextMock.Object, directiveTwo)).Returns(2); _contextMock.InSequence(seq).Setup(p => p.Parameters).Returns(parameters); _contextMock.InSequence(seq).Setup(p => p.Parameters).Returns(parameters); _contextMock.InSequence(seq).Setup(p => p.Request).Returns(_requestMock.Object); _requestMock.InSequence(seq).Setup(p => p.CreateChild(typeof(IWarrior), _contextMock.Object, It.IsAny <ParameterTarget>())).Returns(childRequestMock.Object); childRequestMock.InSequence(seq).SetupSet(p => p.IsUnique = true); _contextMock.InSequence(seq).Setup(p => p.Kernel).Returns(readOnlyKernelMock.Object); readOnlyKernelMock.InSequence(seq).Setup(p => p.ResolveSingle(childRequestMock.Object)).Returns(warriorMock.Object); injectorOneMock.InSequence(seq).Setup(p => p(weaponMock.Object, warriorMock.Object)).Returns(expected); var actual = _standardProvider.Create(_contextMock.Object); Assert.Same(expected, actual); }
/*----------------------------------------------------------------------------------------*/ /// <summary> /// Resolves the arguments for the constructor defined by the specified constructor injection /// directive. /// </summary> /// <param name="context">The context in which the activation is occurring.</param> /// <param name="directive">The directive describing the injection constructor.</param> /// <returns>An array of arguments that can be passed to the constructor.</returns> protected virtual object[] ResolveConstructorArguments(IContext context, ConstructorInjectionDirective directive) { var contextFactory = context.Binding.Components.ContextFactory; var converter = context.Binding.Components.Converter; var arguments = new object[directive.Arguments.Count]; int index = 0; foreach (Argument argument in directive.Arguments) { // First, try to get the value from a context parameter. object value = context.Parameters.GetValueOf <ConstructorArgumentParameter>(argument.Target.Name, context); // Next, try to get the value from a binding parameter. if (value == null) { value = context.Binding.Parameters.GetValueOf <ConstructorArgumentParameter>(argument.Target.Name, context); } // If no overrides have been declared, activate a service of the proper type to use as the value. if (value == null) { // Create a new context in which the parameter's value will be activated. IContext injectionContext = contextFactory.CreateChild(context, directive.Member, argument.Target, argument.Optional); // Resolve the value to inject for the parameter. value = argument.Resolver.Resolve(context, injectionContext); } // Convert the value if necessary. if (!converter.Convert(value, argument.Target.Type, out value)) { throw new ActivationException(ExceptionFormatter.CouldNotConvertValueForInjection(context, argument.Target, value)); } arguments[index++] = value; } return(arguments); }
/// <summary> /// Gets the score for the specified constructor. /// </summary> /// <param name="context">The injection context.</param> /// <param name="directive">The constructor.</param> /// <returns>The constructor's score.</returns> public override int Score(IContext context, ConstructorInjectionDirective directive) { if (context.Request.Service.IsGenericType && context.Request.Service.GetGenericTypeDefinition() == typeof(Lazy <>)) { if (directive.Constructor.GetParameters().Length == 1 && directive.Constructor.GetParameters()[0].ParameterType.IsGenericType) { return(1); } else { return(0); } } else { return(base.Score(context, directive)); } }
/// <summary> /// Adds a <see cref="ConstructorInjectionDirective"/> to the plan for the constructor /// that should be injected. /// </summary> /// <param name="plan">The plan that is being generated.</param> public void Execute(IPlan plan) { var constructors = this.Selector.SelectConstructorsForInjection(plan.Type); if (constructors == null) { return; } foreach (ConstructorInfo constructor in constructors) { var hasInjectAttribute = constructor.HasAttribute(this.Settings.InjectAttribute); var directive = new ConstructorInjectionDirective(constructor, this.InjectorFactory.Create(constructor)) { HasInjectAttribute = hasInjectAttribute }; plan.Add(directive); } }
/// <summary> /// Gets the score for the specified constructor. /// </summary> /// <param name="context">The injection context.</param> /// <param name="directive">The constructor injection directive.</param> /// <returns> /// The constructor's score. /// </returns> /// <exception cref="ArgumentNullException"><paramref name="context"/> is <see langword="null"/>.</exception> /// <exception cref="ArgumentNullException"><paramref name="directive"/> is <see langword="null"/>.</exception> public virtual int Score(IContext context, ConstructorInjectionDirective directive) { Ensure.ArgumentNotNull(context, nameof(context)); Ensure.ArgumentNotNull(directive, nameof(directive)); if (directive.Constructor.HasAttribute(this.settings.InjectAttribute)) { return(int.MaxValue); } if (directive.Constructor.HasAttribute(typeof(ObsoleteAttribute))) { return(int.MinValue); } var score = 1; foreach (ITarget target in directive.Targets) { if (this.ParameterExists(context, target)) { score++; continue; } if (this.BindingExists(context, target)) { score++; continue; } score++; if (score > 0) { score += int.MinValue; } } return(score); }
public void Create_ShouldThrowActivationExceptionWhenThereIsMoreThanOneConstructorInjectionDirectiveWithTheBestScore() { var seq = new MockSequence(); var constructorInjectorMock = new Mock <ConstructorInjector>(MockBehavior.Strict); var directiveOne = new ConstructorInjectionDirective(GetMyServiceWeaponAndWarriorConstructor(), constructorInjectorMock.Object); var directiveTwo = new ConstructorInjectionDirective(GetMyServiceDefaultConstructor(), constructorInjectorMock.Object); var directiveThree = new ConstructorInjectionDirective(GetMyServiceClericAndName(), constructorInjectorMock.Object); var directives = new ConstructorInjectionDirective[] { directiveOne, directiveTwo, directiveThree }; var parameters = new List <IParameter> { new ConstructorArgument("location", "Biutiful"), new ConstructorArgument("warrior", new Monk()), new ConstructorArgument("weapon", new Dagger()) }; var kernelConfiguration = new KernelConfiguration(_ninjectSettings); var context = CreateContext(kernelConfiguration, kernelConfiguration.BuildReadOnlyKernel(), parameters, typeof(NinjaBarracks), _providerCallbackMock.Object, _ninjectSettings); context.Plan = new Plan(typeof(MyService)); context.Plan.Add(directiveOne); context.Plan.Add(directiveTwo); context.Plan.Add(directiveThree); _constructorScorerMock.InSequence(seq).Setup(p => p.Score(context, directiveOne)).Returns(3); _constructorScorerMock.InSequence(seq).Setup(p => p.Score(context, directiveTwo)).Returns(2); _constructorScorerMock.InSequence(seq).Setup(p => p.Score(context, directiveThree)).Returns(3); _providerCallbackMock.InSequence(seq).Setup(p => p(context)).Returns(_providerMock.Object); var actualException = Assert.Throws <ActivationException>(() => _standardProvider.Create(context)); Assert.Null(actualException.InnerException); Assert.Equal(CreateAmbiguousConstructorExceptionMessage(actualException.GetType()), actualException.Message); }
/// <summary> /// Creates an instance within the specified context. /// </summary> /// <param name="context">The context.</param> /// <returns>The created instance.</returns> public virtual object Create(IContext context) { Ensure.ArgumentNotNull(context, "context"); if (context.Plan == null) { context.Plan = this.Planner.GetPlan(this.GetImplementationType(context.Request.Service)); } ConstructorInjectionDirective directive = null; var directives = context.Plan.ConstructorInjectionDirectives; if (directives.Count == 1) { directive = directives[0]; } else { var bestDirectives = directives .GroupBy(option => this.ConstructorScorer.Score(context, option)) .OrderByDescending(g => g.Key) .FirstOrDefault(); if (bestDirectives == null) { throw new ActivationException(ExceptionFormatter.NoConstructorsAvailable(context)); } if (bestDirectives.Skip(1).Any()) { throw new ActivationException(ExceptionFormatter.ConstructorsAmbiguous(context, bestDirectives)); } directive = bestDirectives.First(); } var arguments = directive.Targets.Select(target => this.GetValue(context, target)).ToArray(); return(directive.Injector(arguments)); }
/// <summary> /// Adds a <see cref="ConstructorInjectionDirective"/> to the plan for the constructor /// that should be injected. /// </summary> /// <param name="plan">The plan that is being generated.</param> public void Execute(IPlan plan) { Ensure.ArgumentNotNull(plan, "plan"); var constructors = this.selector.SelectConstructorsForInjection(plan.Type); if (constructors == null) { return; } foreach (ConstructorInfo constructor in constructors) { var hasInjectAttribute = constructor.HasAttribute(this.settings.InjectAttribute); var hasObsoleteAttribute = constructor.HasAttribute(typeof(ObsoleteAttribute)); var directive = new ConstructorInjectionDirective(constructor, this.injectorFactory.Create(constructor)) { HasInjectAttribute = hasInjectAttribute, HasObsoleteAttribute = hasObsoleteAttribute, }; plan.Add(directive); } }
public void Create_ShouldThrowActivationExceptionWhenThereAreZeroConstructorInjectionDirectives() { var directives = new ConstructorInjectionDirective[0]; var parameters = new List <IParameter> { new ConstructorArgument("location", "Biutiful"), new ConstructorArgument("warrior", new Monk()), new ConstructorArgument("weapon", new Dagger()) }; var kernelConfiguration = new KernelConfiguration(_ninjectSettings); var context = CreateContext(kernelConfiguration, kernelConfiguration.BuildReadOnlyKernel(), parameters, typeof(NinjaBarracks), _providerCallbackMock.Object, _ninjectSettings); context.Plan = new Plan(typeof(NinjaBarracks)); _providerCallbackMock.Setup(p => p(context)).Returns(_providerMock.Object); var actualException = Assert.Throws <ActivationException>(() => _standardProvider.Create(context)); Assert.Null(actualException.InnerException); Assert.Equal(CreateNoConstructorAvailableExceptionMessage(), actualException.Message); _providerCallbackMock.Verify(p => p(context), Times.Once()); }
/// <summary> /// Gets the score for the specified constructor. /// </summary> /// <param name="context">The injection context.</param> /// <param name="directive">The constructor injection directive.</param> /// <returns>The constructor's score.</returns> public virtual int Score(IContext context, ConstructorInjectionDirective directive) { return(directive.Constructor.Equals(this.constructorInfo) ? 1 : 0); }
/// <summary> /// Gets the score for the specified constructor. /// </summary> /// <param name="context">The injection context.</param> /// <param name="directive">The constructor.</param> /// <returns>The constructor's score.</returns> public virtual int Score(IContext context, ConstructorInjectionDirective directive) { return directive.Constructor.Equals(this.constructorInfo) ? 1 : 0; }
public override int Score(IContext context, ConstructorInjectionDirective directive) { return directive.Targets.Length; }
/*----------------------------------------------------------------------------------------*/ /// <summary> /// Resolves the arguments for the constructor defined by the specified constructor injection /// directive. /// </summary> /// <param name="context">The context in which the activation is occurring.</param> /// <param name="directive">The directive describing the injection constructor.</param> /// <returns>An array of arguments that can be passed to the constructor.</returns> protected virtual object[] ResolveConstructorArguments(IContext context, ConstructorInjectionDirective directive) { var contextFactory = context.Binding.Components.ContextFactory; var converter = context.Binding.Components.Converter; var arguments = new object[directive.Arguments.Count]; int index = 0; foreach (Argument argument in directive.Arguments) { // First, try to get the value from a context parameter. object value = context.Parameters.GetValueOf<ConstructorArgumentParameter>(argument.Target.Name, context); // Next, try to get the value from a binding parameter. if (value == null) value = context.Binding.Parameters.GetValueOf<ConstructorArgumentParameter>(argument.Target.Name, context); // If no overrides have been declared, activate a service of the proper type to use as the value. if (value == null) { // Create a new context in which the parameter's value will be activated. IContext injectionContext = contextFactory.CreateChild(context, directive.Member, argument.Target, argument.Optional); // Resolve the value to inject for the parameter. value = argument.Resolver.Resolve(context, injectionContext); } // Convert the value if necessary. if (!converter.Convert(value, argument.Target.Type, out value)) throw new ActivationException(ExceptionFormatter.CouldNotConvertValueForInjection(context, argument.Target, value)); arguments[index++] = value; } return arguments; }