/*----------------------------------------------------------------------------------------*/ #region Public Methods /// <summary> /// Registers a new binding. /// </summary> /// <param name="binding">The binding to register.</param> public void Add(IBinding binding) { Ensure.ArgumentNotNull(binding, "binding"); Ensure.NotDisposed(this); lock (_bindings) { if (Logger.IsDebugEnabled) { Logger.Debug("Adding {0}", Format.Binding(binding)); } _bindings.Add(binding.Service, binding); } }
/*----------------------------------------------------------------------------------------*/ #region Protected Methods: Bindings /// <summary> /// Determines which binding should be used for the specified service in the specified context. /// </summary> /// <param name="service">The type whose binding is to be resolved.</param> /// <param name="context">The context in which the binding is being resolved.</param> /// <returns>The selected binding.</returns> protected virtual IBinding ResolveBinding(Type service, IContext context) { Ensure.NotDisposed(this); IBinding binding = Components.BindingSelector.SelectBinding(service, context); // If the requested service type is generic, try to resolve a binding for its generic type definition. if (binding == null && service.IsGenericType && !service.IsGenericTypeDefinition) { Type genericTypeDefinition = service.GetGenericTypeDefinition(); if (Logger.IsDebugEnabled) { Logger.Debug("Couldn't find binding for actual service type {0}, trying for generic type definition {1}", Format.Type(service), Format.Type(genericTypeDefinition)); } binding = Components.BindingSelector.SelectBinding(genericTypeDefinition, context); } // If there was no explicit binding defined, see if we can create an implicit self-binding. if (binding == null && Options.ImplicitSelfBinding && StandardProvider.CanSupportType(service)) { if (Logger.IsDebugEnabled) { Logger.Debug("No binding exists for service {0}, creating implicit self-binding", Format.Type(service)); } binding = CreateImplicitSelfBinding(service); AddBinding(binding); } if (Logger.IsDebugEnabled) { if (binding == null) { Logger.Debug("No binding exists for service {0}, and type is not self-bindable or generic", Format.Type(service)); } else { Logger.Debug("Selected {0} for service {1}", Format.Binding(binding), Format.Type(service)); } } return(binding); }
/*----------------------------------------------------------------------------------------*/ #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); } }
/*----------------------------------------------------------------------------------------*/ /// <summary> /// Releases the specified binding. /// </summary> /// <param name="binding">The binding.</param> public void Release(IBinding binding) { Ensure.ArgumentNotNull(binding, "binding"); Ensure.NotDisposed(this); lock (_bindings) { Type service = binding.Service; if (Logger.IsDebugEnabled) { Logger.Debug("Releasing {0}", Format.Binding(binding)); } if (!_bindings.ContainsKey(service) || !_bindings.Remove(service, binding)) { throw new InvalidOperationException(ExceptionFormatter.CannotReleaseUnregisteredBinding(binding)); } } }