/// <summary> /// Find best matched component for type/name or null for /// </summary> /// <param name="type"> The type. </param> /// <param name="name"> The name. </param> /// <returns> </returns> /// <exception cref="NotImplementedException"></exception> /// <remarks> /// </remarks> public IComponentDefinition FindComponent(Type type, string name) { type = type ?? typeof(object); var preresult = PreFindComponentWithSubResolvers(type, name); if (null != preresult) { return(preresult); } if (name.IsEmpty()) { //firstly try to direct match if (ByTypeCache.ContainsKey(type)) { return(ByTypeCache[type].FirstOrDefault()); } var key = ByTypeCache.Keys.FirstOrDefault(type.IsAssignableFrom); if (null == key) { return(PostFindComponentWithSubResolvers(type, name)); } return(ByTypeCache[key].FirstOrDefault()); } if (!ByNameCache.ContainsKey(name)) { return(PostFindComponentWithSubResolvers(type, name)); } return(ByNameCache[name].FirstOrDefault(x => type.IsAssignableFrom(x.ServiceType))); }
/// <summary> /// Find best matched extension (extension, transient, default - lifesycle) components for type/name /// </summary> /// <param name="type"> The type. </param> /// <param name="name"> The name. </param> /// <returns> </returns> /// <exception cref="NotImplementedException"></exception> /// <remarks> /// </remarks> public IEnumerable <IComponentDefinition> FindExtensions(Type type, string name, bool includeall = false) { if (name.IsEmpty()) { if (!ByTypeCache.ContainsKey(type)) { return(new IComponentDefinition[] {}); } return (ByTypeCache[type].Where( x => includeall || ((Lifestyle.Transient | Lifestyle.Extension | Lifestyle.Default) & x.Lifestyle) != 0).Reverse().ToArray()); } //поддержка поиска по тегам if (name.StartsWith("tag:")) { var regex = new Regex(name.Substring(4)); return(Components.Where( x => (includeall || ((Lifestyle.Transient | Lifestyle.Extension | Lifestyle.Default) & x.Lifestyle) != 0) && (null != x.Tag && regex.IsMatch(x.Tag)) ).Reverse().ToArray()); } if (name.StartsWith("~")) { var regex = new Regex(name.Substring(1)); return(Components.Where( x => (includeall || ((Lifestyle.Transient | Lifestyle.Extension | Lifestyle.Default) & x.Lifestyle) != 0) && (null != x.Name && regex.IsMatch(x.Name)) ).Reverse().ToArray()); } if (!ByNameCache.ContainsKey(name)) { return(new IComponentDefinition[] { }); } return(ByNameCache[name].Where( x => type.IsAssignableFrom(x.ServiceType) && ((Lifestyle.Transient | Lifestyle.Extension | Lifestyle.Default) & x.Lifestyle) != 0 ).Reverse().ToArray()); }
/// <summary> /// Регистрирует новый компонент в контейнере /// </summary> public void Register(IComponentDefinition component) { lock (this) { #if PARANOID if (component.ServiceType == typeof(IRoleResolver)) { if (component.ImplementationType != typeof(DefaultRoleResolver)) { throw new ParanoidException(ParanoidState.InvalidRoleResolver); } } if (component.ServiceType == typeof(IPrincipalSource)) { if (component.ImplementationType != typeof(DefaultPrincipalSource)) { throw new ParanoidException(ParanoidState.InvalidPrincipalSource); } } #endif Log.Debug("Start register " + component, this); // redirect logic for container extensions - they are processed on their own manner // and container extensions don't trigger RegisterComponent event if (component.Lifestyle == Lifestyle.ContainerExtension) { if (null == _extensions.FirstOrDefault(x => x.GetType() == component.ImplementationType)) { RegisterExtension((IContainerExtension)Activator.CreateInstance(component.ImplementationType)); } return; } // hook for extensions - RegisterComponent extensions can replace/update/Prepare component to be registered // it can be used only BEFORE native registration due to index integrity component = ProcessExtensions(new ContainerContext { Operation = ContainerOperation.BeforeRegisterComponent, Component = component }).Component; //no need double registration if (ComponentExists(component)) { return; } component.ContainerId = CurrentComponentId++; Components.Add(component); if (!ByTypeCache.ContainsKey(component.ServiceType)) { ByTypeCache[component.ServiceType] = new List <IComponentDefinition>(); } ByTypeCache[component.ServiceType].Add(component); ByTypeCache[component.ServiceType].Sort(CompareComponents); if (component.Name.IsNotEmpty()) { if (!ByNameCache.ContainsKey(component.Name)) { ByNameCache[component.Name] = new List <IComponentDefinition>(); } ByNameCache[component.Name].Add(component); ByNameCache[component.Name].Sort(CompareComponents); } ProcessExtensions(new ContainerContext { Operation = ContainerOperation.AfterRegisterComponent, Component = component }); Log.Debug("Registered " + component, this); } }