/*----------------------------------------------------------------------------------------*/ #region Public Methods /// <summary> /// Selects the constructor that should be called to create an instance of the type. /// </summary> /// <param name="binding">The binding that points at the type whose activation plan being manipulated.</param> /// <param name="plan">The activation plan that is being manipulated.</param> /// <param name="candidates">The candidate constructors that are available.</param> /// <returns>The selected constructor.</returns> public virtual ConstructorInfo SelectConstructor(IBinding binding, IActivationPlan plan, IList <ConstructorInfo> candidates) { // If there was only a single constructor defined for the type, try to use it. if (candidates.Count == 1) { return(candidates[0]); } ConstructorInfo selectedConstructor = null; foreach (ConstructorInfo constructor in candidates) { if (!Heuristics.ShouldInject(binding, plan, candidates, constructor) && !binding.Heuristics.ShouldInject(binding, plan, candidates, constructor)) { continue; } // Only a single injection constructor is allowed, so fail if we find more than one. if (selectedConstructor != null) { throw new NotSupportedException(ExceptionFormatter.MultipleInjectionConstructorsNotSupported(binding)); } selectedConstructor = constructor; } // If no constructors were selected for injection, try to use the default one. if (selectedConstructor == null) { selectedConstructor = plan.Type.GetConstructor(new Type[0]); } return(selectedConstructor); }
/*----------------------------------------------------------------------------------------*/ /// <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) { if (binding.Behavior != null) { // If the binding declares a behavior, it overrides any behavior that would be read // via reflection. plan.Behavior = binding.Behavior; } else { IBehavior behavior; var attribute = type.GetOneAttribute<BehaviorAttribute>(); if (attribute != null) { // If a behavior attribute was defined on the implementation type, ask it to create // the appropriate behavior. behavior = attribute.CreateBehavior(); } else { // If no behavior attribute was defined, create a behavior as defined by the kernel's options. behavior = Activator.CreateInstance(Kernel.Options.DefaultBehaviorType) as IBehavior; } behavior.Kernel = Kernel; plan.Behavior = behavior; } return StrategyResult.Proceed; }
/*----------------------------------------------------------------------------------------*/ /// <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) { if (binding.Behavior != null) { // If the binding declares a behavior, it overrides any behavior that would be read // via reflection. plan.Behavior = binding.Behavior; } else { IBehavior behavior; var attribute = type.GetOneAttribute <BehaviorAttribute>(); if (attribute != null) { // If a behavior attribute was defined on the implementation type, ask it to create // the appropriate behavior. behavior = attribute.CreateBehavior(); } else { // If no behavior attribute was defined, create a behavior as defined by the kernel's options. behavior = Activator.CreateInstance(Kernel.Options.DefaultBehaviorType) as IBehavior; } behavior.Kernel = Kernel; plan.Behavior = behavior; } return(StrategyResult.Proceed); }
/*----------------------------------------------------------------------------------------*/ /// <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) { EventInfo[] events = type.GetEvents(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); foreach (EventInfo evt in events) { #if !MONO PublishAttribute[] attributes = evt.GetAllAttributes<PublishAttribute>(); #else PublishAttribute[] attributes = ExtensionsForICustomAttributeProvider.GetAllAttributes<PublishAttribute>(evt); #endif foreach (PublishAttribute attribute in attributes) plan.Directives.Add(new PublicationDirective(attribute.Channel, evt)); } MethodInfo[] methods = type.GetMethods(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); var injectorFactory = binding.Components.Get<IInjectorFactory>(); foreach (MethodInfo method in methods) { #if !MONO SubscribeAttribute[] attributes = method.GetAllAttributes<SubscribeAttribute>(); #else SubscribeAttribute[] attributes = ExtensionsForICustomAttributeProvider.GetAllAttributes<SubscribeAttribute>(method); #endif foreach (SubscribeAttribute attribute in attributes) { IMethodInjector injector = injectorFactory.GetInjector(method); plan.Directives.Add(new SubscriptionDirective(attribute.Channel, injector, attribute.Thread)); } } return StrategyResult.Proceed; }
/*----------------------------------------------------------------------------------------*/ /// <summary> /// Returns a value indicating whether the specified member should be injected during activation. /// </summary> /// <param name="binding">The binding that points at the type whose activation plan being manipulated.</param> /// <param name="plan">The activation plan that is being manipulated.</param> /// <param name="candidates">The candidates that are available.</param> /// <param name="member">The member in question.</param> /// <returns><see langword="True"/> if the member should be injected, otherwise <see langword="false"/>.</returns> public override bool ShouldInject(IBinding binding, IActivationPlan plan, IEnumerable <PropertyInfo> candidates, PropertyInfo member) { var registry = binding.Components.BindingRegistry; if (member.CanWrite && (member.GetSetMethod() != null) && registry.HasBinding(member.PropertyType)) { return(true); } return(base.ShouldInject(binding, plan, candidates, member)); }
/*----------------------------------------------------------------------------------------*/ /// <summary> /// Returns a value indicating whether the specified member should be injected during activation. /// </summary> /// <param name="binding">The binding that points at the type whose activation plan being manipulated.</param> /// <param name="plan">The activation plan that is being manipulated.</param> /// <param name="candidates">The candidates that are available.</param> /// <param name="member">The member in question.</param> /// <returns><see langword="True"/> if the member should be injected, otherwise <see langword="false"/>.</returns> public bool ShouldInject(IBinding binding, IActivationPlan plan, IEnumerable <MethodInfo> candidates, MethodInfo member) { var registry = binding.Components.BindingRegistry; ParameterInfo[] parameters = member.GetParameters(); #if !MONO return(parameters.Length > 0 && parameters.Convert(p => p.ParameterType).All(registry.HasBinding)); #else return(parameters.Length > 0 && ExtensionsForIEnumerable.All( ExtensionsForIEnumerable.Convert(parameters, p => p.ParameterType), registry.HasBinding)); #endif }
/*----------------------------------------------------------------------------------------*/ /// <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> /// 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> /// Registers static interceptors defined by attributes on the class for all candidate /// methods on the class, execept those decorated with a <see cref="DoNotInterceptAttribute"/>. /// </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> /// <param name="candidates">The candidate methods to intercept.</param> protected virtual void RegisterClassInterceptors(IBinding binding, Type type, IActivationPlan plan, IEnumerable<MethodInfo> candidates) { InterceptAttribute[] attributes = type.GetAllAttributes<InterceptAttribute>(); if (attributes.Length == 0) return; foreach (MethodInfo method in candidates) { if (!method.HasAttribute<DoNotInterceptAttribute>()) RegisterMethodInterceptors(binding, type, plan, method, attributes); } // Indicate that instances of the type should be proxied. plan.Directives.Add(new ProxyDirective()); }
/*----------------------------------------------------------------------------------------*/ #region Public Methods /// <summary> /// Builds a new activation plan by inspecting the specified type. /// </summary> /// <param name="binding">The binding that was used to resolve the type being activated.</param> /// <param name="type">The type to examine.</param> /// <returns>An activation plan that will be used to build instances type.</returns> public IActivationPlan GetPlan(IBinding binding, Type type) { Ensure.ArgumentNotNull(binding, "binding"); Ensure.ArgumentNotNull(type, "type"); Ensure.NotDisposed(this); lock (Plans) { if (Logger.IsDebugEnabled) { Logger.Debug("Activation plan for type {0} requested by {1}", Format.Type(type), Format.Binding(binding)); } if (Plans.ContainsKey(type)) { if (Logger.IsDebugEnabled) { Logger.Debug("Using already-generated plan from cache"); } return(Plans[type]); } IActivationPlan plan = binding.Components.ActivationPlanFactory.Create(type); Plans.Add(type, plan); if (Logger.IsDebugEnabled) { Logger.Debug("Type has not been analyzed, building activation plan"); } Strategies.ExecuteForChain(s => s.BeforeBuild(binding, type, plan)); Strategies.ExecuteForChain(s => s.Build(binding, type, plan)); Strategies.ExecuteForChain(s => s.AfterBuild(binding, type, plan)); if (Logger.IsDebugEnabled) { Logger.Debug("Activation plan for {0} built successfully", Format.Type(type)); } return(plan); } }
/*----------------------------------------------------------------------------------------*/ #region Public Methods /// <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) { IEnumerable <TMember> candidates; // If non-public members should be included, we have to scan the type hierarchy recursively. if (Kernel.Options.InjectNonPublicMembers) { candidates = GetCandidatesRecursive(binding, type); } else { candidates = GetCandidates(binding, type, BindingFlags.Public | BindingFlags.Instance); } // Add injection directives for each candidate member that matches the heuristic. foreach (TMember member in binding.Components.MemberSelector.SelectMembers(binding, plan, candidates)) { AddInjectionDirective(binding, type, plan, member); } return(StrategyResult.Proceed); }
/*----------------------------------------------------------------------------------------*/ /// <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) { IEnumerable<MethodInfo> candidates = GetCandidateMethods(type); RegisterClassInterceptors(binding, type, plan, candidates); foreach (MethodInfo method in candidates) { InterceptAttribute[] attributes = method.GetAllAttributes<InterceptAttribute>(); if (attributes.Length > 0) { RegisterMethodInterceptors(binding, type, plan, method, attributes); // Indicate that instances of the type should be proxied. if (!plan.Directives.HasOneOrMore<ProxyDirective>()) plan.Directives.Add(new ProxyDirective()); } } return StrategyResult.Proceed; }
/*----------------------------------------------------------------------------------------*/ /// <summary> /// Releases the activation plan for the specified type, if one was created. /// </summary> /// <param name="binding">The binding which points to the type that should be released.</param> /// <param name="type">The type whose activation plan should be released.</param> public void ReleasePlan(IBinding binding, Type type) { Ensure.ArgumentNotNull(binding, "binding"); Ensure.ArgumentNotNull(type, "type"); Ensure.NotDisposed(this); lock (Plans) { if (Logger.IsDebugEnabled) { Logger.Debug("Releasing activation plan for type {0}", Format.Type(type)); } if (!Plans.ContainsKey(type)) { if (Logger.IsDebugEnabled) { Logger.Debug("Activation plan for {0} has not been created or was already released, ignoring", Format.Type(type)); } return; } IActivationPlan plan = Plans[type]; Strategies.ExecuteForChain(s => s.BeforeRelease(binding, type, plan)); Strategies.ExecuteForChain(s => s.Release(binding, type, plan)); Strategies.ExecuteForChain(s => s.AfterRelease(binding, type, plan)); Plans.Remove(type); if (Logger.IsDebugEnabled) { Logger.Debug("Finished releasing activation plan for type {0}", Format.Type(type)); } } }
/*----------------------------------------------------------------------------------------*/ /// <summary> /// Returns a value indicating whether the specified member should be injected during activation. /// </summary> /// <param name="binding">The binding that points at the type whose activation plan being manipulated.</param> /// <param name="plan">The activation plan that is being manipulated.</param> /// <param name="candidates">The candidates that are available.</param> /// <param name="member">The member in question.</param> /// <returns> /// <see langword="True"/> if the member should be injected, otherwise <see langword="false"/>. /// </returns> public bool ShouldInject(IBinding binding, IActivationPlan plan, IEnumerable <ConstructorInfo> candidates, ConstructorInfo member) { #if !MONO var list = candidates.ToList(); #else var list = ExtensionsForIEnumerable.ToList(candidates); #endif if (list.Count == 1) { return(true); } var registry = binding.Components.BindingRegistry; #if !MONO return(member == candidates.Best(c => c.GetParameterTypes().Count(registry.HasBinding))); #else return(member == ExtensionsForIEnumerable .Best(candidates, c => ExtensionsForIEnumerable.Count(ExtensionsForMethodBase.GetParameterTypes(c), registry.HasBinding))); #endif }
public void EagerActivationCausesSingletonInstancesToBeImmediatelyActivated() { var module = new InlineModule(m => m.Bind <ObjectWithSingletonBehavior>().ToSelf()); var options = new KernelOptions { UseEagerActivation = true }; using (var kernel = new StandardKernel(options, module)) { Type type = typeof(ObjectWithSingletonBehavior); IContext context = kernel.Components.ContextFactory.Create(type); IBinding binding = kernel.Components.BindingSelector.SelectBinding(type, context); Assert.That(binding, Is.Not.Null); IActivationPlan plan = binding.Components.Planner.GetPlan(binding, type); var behavior = plan.Behavior as SingletonBehavior; Assert.That(behavior, Is.Not.Null); Assert.That(behavior.ContextCache, Is.Not.Empty); } }
/*----------------------------------------------------------------------------------------*/ /// <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) { EventInfo[] events = type.GetEvents(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); foreach (EventInfo evt in events) { #if !MONO PublishAttribute[] attributes = evt.GetAllAttributes <PublishAttribute>(); #else PublishAttribute[] attributes = ExtensionsForICustomAttributeProvider.GetAllAttributes <PublishAttribute>(evt); #endif foreach (PublishAttribute attribute in attributes) { plan.Directives.Add(new PublicationDirective(attribute.Channel, evt)); } } MethodInfo[] methods = type.GetMethods(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); var injectorFactory = binding.Components.Get <IInjectorFactory>(); foreach (MethodInfo method in methods) { #if !MONO SubscribeAttribute[] attributes = method.GetAllAttributes <SubscribeAttribute>(); #else SubscribeAttribute[] attributes = ExtensionsForICustomAttributeProvider.GetAllAttributes <SubscribeAttribute>(method); #endif foreach (SubscribeAttribute attribute in attributes) { IMethodInjector injector = injectorFactory.GetInjector(method); plan.Directives.Add(new SubscriptionDirective(attribute.Channel, injector, attribute.Thread)); } } return(StrategyResult.Proceed); }
/*----------------------------------------------------------------------------------------*/ /// <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) { IEnumerable <MethodInfo> candidates = GetCandidateMethods(type); RegisterClassInterceptors(binding, type, plan, candidates); foreach (MethodInfo method in candidates) { InterceptAttribute[] attributes = method.GetAllAttributes <InterceptAttribute>(); if (attributes.Length > 0) { RegisterMethodInterceptors(binding, type, plan, method, attributes); // Indicate that instances of the type should be proxied. if (!plan.Directives.HasOneOrMore <ProxyDirective>()) { plan.Directives.Add(new ProxyDirective()); } } } return(StrategyResult.Proceed); }
/*----------------------------------------------------------------------------------------*/ /// <summary> /// Executed to release 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 virtual StrategyResult Release(IBinding binding, Type type, IActivationPlan plan) { return(StrategyResult.Proceed); }
/*----------------------------------------------------------------------------------------*/ /// <summary> /// Executed before the activation plan is built. /// </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 virtual StrategyResult BeforeBuild(IBinding binding, Type type, IActivationPlan plan) { return(StrategyResult.Proceed); }
/*----------------------------------------------------------------------------------------*/ /// <summary> /// Registers static interceptors defined by attributes on the specified method. /// </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> /// <param name="method">The method that may be intercepted.</param> /// <param name="attributes">The interception attributes that apply.</param> protected virtual void RegisterMethodInterceptors(IBinding binding, Type type, IActivationPlan plan, MethodInfo method, ICollection <InterceptAttribute> attributes) { var factory = binding.Components.AdviceFactory; var registry = binding.Components.AdviceRegistry; foreach (InterceptAttribute attribute in attributes) { IAdvice advice = factory.Create(method); advice.Callback = attribute.CreateInterceptor; advice.Order = attribute.Order; registry.Register(advice); } }
/*----------------------------------------------------------------------------------------*/ /// <summary> /// Returns a value indicating whether the specified member should be injected during activation. /// </summary> /// <param name="binding">The binding that points at the type whose activation plan being manipulated.</param> /// <param name="plan">The activation plan that is being manipulated.</param> /// <param name="candidates">The candidates that are available.</param> /// <param name="member">The member in question.</param> /// <returns><see langword="True"/> if the member should be injected, otherwise <see langword="false"/>.</returns> public virtual bool ShouldInject(IBinding binding, IActivationPlan plan, IEnumerable <TMember> candidates, TMember member) { return(member.HasAttribute(binding.Kernel.Options.InjectAttributeType)); }
/*----------------------------------------------------------------------------------------*/ /// <summary> /// Selects the members of the specified type that should be injected. /// </summary> /// <typeparam name="TMember">The type of member to consider.</typeparam> /// <param name="binding">The binding that points at the type whose activation plan being manipulated.</param> /// <param name="plan">The activation plan that is being manipulated.</param> /// <param name="candidates">The candidate members that are available.</param> /// <returns>A series of members that should be injected.</returns> public virtual IEnumerable <TMember> SelectMembers <TMember>(IBinding binding, IActivationPlan plan, IEnumerable <TMember> candidates) where TMember : MemberInfo { return(candidates.Where(m => Heuristics.ShouldInject(binding, plan, candidates, m) || binding.Heuristics.ShouldInject(binding, plan, candidates, m))); }
/*----------------------------------------------------------------------------------------*/ /// <summary> /// Registers static interceptors defined by attributes on the class for all candidate /// methods on the class, execept those decorated with a <see cref="DoNotInterceptAttribute"/>. /// </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> /// <param name="candidates">The candidate methods to intercept.</param> protected virtual void RegisterClassInterceptors(IBinding binding, Type type, IActivationPlan plan, IEnumerable <MethodInfo> candidates) { InterceptAttribute[] attributes = type.GetAllAttributes <InterceptAttribute>(); if (attributes.Length == 0) { return; } foreach (MethodInfo method in candidates) { if (!method.HasAttribute <DoNotInterceptAttribute>()) { RegisterMethodInterceptors(binding, type, plan, method, attributes); } } // Indicate that instances of the type should be proxied. plan.Directives.Add(new ProxyDirective()); }
/*----------------------------------------------------------------------------------------*/ /// <summary> /// Adds an injection directive related to the specified member to the specified activation plan. /// </summary> /// <param name="binding">The binding that points at the type being inspected.</param> /// <param name="type">The type that is being inspected.</param> /// <param name="plan">The activation plan to add the directive to.</param> /// <param name="member">The member to create a directive for.</param> protected override void AddInjectionDirective(IBinding binding, Type type, IActivationPlan plan, FieldInfo member) { FieldInjectionDirective directive = binding.Components.DirectiveFactory.Create(binding, member); plan.Directives.Add(directive); }
/*----------------------------------------------------------------------------------------*/ /// <summary> /// Registers static interceptors defined by attributes on the specified method. /// </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> /// <param name="method">The method that may be intercepted.</param> /// <param name="attributes">The interception attributes that apply.</param> protected virtual void RegisterMethodInterceptors(IBinding binding, Type type, IActivationPlan plan, MethodInfo method, ICollection<InterceptAttribute> attributes) { var factory = binding.Components.AdviceFactory; var registry = binding.Components.AdviceRegistry; foreach (InterceptAttribute attribute in attributes) { IAdvice advice = factory.Create(method); advice.Callback = attribute.CreateInterceptor; advice.Order = attribute.Order; registry.Register(advice); } }
/*----------------------------------------------------------------------------------------*/ /// <summary> /// Returns a value indicating whether the specified member should be injected during activation. /// </summary> /// <param name="binding">The binding that points at the type whose activation plan being manipulated.</param> /// <param name="plan">The activation plan that is being manipulated.</param> /// <param name="candidates">The candidates that are available.</param> /// <param name="member">The member in question.</param> /// <returns><see langword="True"/> if the member should be injected, otherwise <see langword="false"/>.</returns> public bool ShouldInject(IBinding binding, IActivationPlan plan, IEnumerable <FieldInfo> candidates, FieldInfo member) { return(binding.Components.BindingRegistry.HasBinding(member.FieldType)); }
/*----------------------------------------------------------------------------------------*/ /// <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 virtual StrategyResult Build(IBinding binding, Type type, IActivationPlan plan) { return StrategyResult.Proceed; }
/*----------------------------------------------------------------------------------------*/ /// <summary> /// Returns a value indicating whether the specified member should be injected during activation. /// </summary> /// <param name="binding">The binding that points at the type whose activation plan being manipulated.</param> /// <param name="plan">The activation plan that is being manipulated.</param> /// <param name="candidates">The candidates that are available.</param> /// <param name="member">The member in question.</param> /// <returns><see langword="True"/> if the member should be injected, otherwise <see langword="false"/>.</returns> public bool ShouldInject(IBinding binding, IActivationPlan plan, IEnumerable <TMember> candidates, TMember member) { return(Condition.Matches(member)); }
/*----------------------------------------------------------------------------------------*/ /// <summary> /// Executed before the activation plan is released. /// </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 virtual StrategyResult AfterRelease(IBinding binding, Type type, IActivationPlan plan) { return StrategyResult.Proceed; }
/*----------------------------------------------------------------------------------------*/ /// <summary> /// Adds an injection directive related to the specified member to the specified activation plan. /// </summary> /// <param name="binding">The binding that points at the type being inspected.</param> /// <param name="type">The type that is being inspected.</param> /// <param name="plan">The activation plan to add the directive to.</param> /// <param name="member">The member to create a directive for.</param> protected abstract void AddInjectionDirective(IBinding binding, Type type, IActivationPlan plan, TMember member);
/*----------------------------------------------------------------------------------------*/ /// <summary> /// Returns a value indicating whether at least one of the registered heuristics indicates /// that the specified member should be injected. /// </summary> /// <typeparam name="TMember"></typeparam> /// <param name="binding">The binding that points at the type whose activation plan being manipulated.</param> /// <param name="plan">The activation plan that is being manipulated.</param> /// <param name="candidates">The candidates that are available.</param> /// <param name="member">The member in question.</param> /// <returns><see langword="True"/> if the member should be injected, otherwise <see langword="false"/>.</returns> public bool ShouldInject <TMember>(IBinding binding, IActivationPlan plan, IEnumerable <TMember> candidates, TMember member) where TMember : MemberInfo { return(GetAll <TMember>().Has(h => h.ShouldInject(binding, plan, candidates, member))); }