/// <summary> /// Stops the context. Note: You can only call this method once per Context. /// </summary> public void Stop() { AssertState(ContextState.Started); lock (_contextMutex) { AssertState(ContextState.Started); State = ContextState.Stopping; foreach (KeyValuePair <string, object> kvp in singletonsByName) { ComponentDescriptor descriptor = null; if (descriptorNameCache.TryGetValue(kvp.Key, out descriptor)) { foreach (IComponentLifecycleProcessor componentLifecycleProcessor in componentLifecycleProcessors) { componentLifecycleProcessor.OnStop(this, kvp.Value, descriptor); } } } singletonsByName.Clear(); singletonsByType.Clear(); descriptorTypeCache.Clear(); descriptorNameCache.Clear(); State = ContextState.Stopping; } }
/// <summary> /// Resolves an injection to a Component. /// </summary> /// <param name="context"></param> /// <param name="componentDescriptor"></param> /// <param name="injectDescriptor"></param> /// <returns></returns> public object ResolveInject(Context context, ComponentDescriptor componentDescriptor, InjectDescriptor injectDescriptor) { ComponentDescriptor injectComponent = null; if (injectDescriptor.Attributes.Name != null) { context.descriptorNameCache.TryGetValue(injectDescriptor.Attributes.Name, out injectComponent); } if (injectDescriptor.Attributes.Type != null) { if (injectComponent == null) { context.descriptorTypeCache.TryGetValue(injectDescriptor.Attributes.Type.AssemblyQualifiedName, out injectComponent); } else { if (injectComponent.Type != injectDescriptor.Attributes.Type) { injectComponent = null; } } } else { context.descriptorTypeCache.TryGetValue(injectDescriptor.Type.AssemblyQualifiedName, out injectComponent); } return injectComponent == null ? null : context.GetInstance(injectComponent); }
/// <summary> /// Resolves an injection to a Component. /// </summary> /// <param name="context"></param> /// <param name="componentDescriptor"></param> /// <param name="injectDescriptor"></param> /// <returns></returns> public object ResolveInject(Context context, ComponentDescriptor componentDescriptor, InjectDescriptor injectDescriptor) { ComponentDescriptor injectComponent = null; if (injectDescriptor.Attributes.Name != null) { context.descriptorNameCache.TryGetValue(injectDescriptor.Attributes.Name, out injectComponent); } if (injectDescriptor.Attributes.Type != null) { if (injectComponent == null) { context.descriptorTypeCache.TryGetValue(injectDescriptor.Attributes.Type.AssemblyQualifiedName, out injectComponent); } else { if (injectComponent.Type != injectDescriptor.Attributes.Type) { injectComponent = null; } } } else { context.descriptorTypeCache.TryGetValue(injectDescriptor.Type.AssemblyQualifiedName, out injectComponent); } return(injectComponent == null ? null : context.GetInstance(injectComponent)); }
/// <summary> /// Resolves Context injections. /// </summary> /// <param name="context"></param> /// <param name="componentDescriptor"></param> /// <param name="injectDescriptor"></param> /// <returns></returns> public object ResolveInject(Context context, ComponentDescriptor componentDescriptor, InjectDescriptor injectDescriptor) { if (injectDescriptor.Type.Equals(context.GetType().AssemblyQualifiedName)) { return context; } return null; }
/// <summary> /// Resolves Context injections. /// </summary> /// <param name="context"></param> /// <param name="componentDescriptor"></param> /// <param name="injectDescriptor"></param> /// <returns></returns> public object ResolveInject(Context context, ComponentDescriptor componentDescriptor, InjectDescriptor injectDescriptor) { if (injectDescriptor.Type.Equals(context.GetType().AssemblyQualifiedName)) { return(context); } return(null); }
/// <summary> /// Notifies the given component when the Context stops. /// </summary> /// <param name="context"></param> /// <param name="component"></param> /// <param name="descriptor"></param> public void OnStop(Context context, object component, ComponentDescriptor descriptor) { foreach (MemberInfo member in descriptor.Type.GetMembers(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance)) { if (member is MethodInfo) { if (member.GetCustomAttribute <OnStopAttribute>() != null) { ((MethodInfo)member).Invoke(component, new object[0]); } } } }
/// <summary> /// Notifies the given component when the Context stops. /// </summary> /// <param name="context"></param> /// <param name="component"></param> /// <param name="descriptor"></param> public void OnStop(Context context, object component, ComponentDescriptor descriptor) { foreach (MemberInfo member in descriptor.Type.GetMembers(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance)) { if (member is MethodInfo) { if (member.GetCustomAttribute<OnStopAttribute>() != null) { ((MethodInfo)member).Invoke(component, new object[0]); } } } }
/// <summary> /// Registers a components of the given type and attributes. /// </summary> /// <param name="type"></param> /// <param name="componentAttribute"></param> private void RegisterComponent(Type type, ComponentAttribute componentAttribute) { lock (_contextMutex) { AssertState(ContextState.Created); if (componentAttribute.Name == null) { componentAttribute.Name = type.Name; } ComponentDescriptor existingDescriptor = null; if (descriptorNameCache.TryGetValue(componentAttribute.Name, out existingDescriptor)) { ComponentDescriptor descriptor = descriptorNameCache[componentAttribute.Name]; if (!existingDescriptor.Type.AssemblyQualifiedName.Equals(type.AssemblyQualifiedName)) { throw new ComponentNameException("Component name '" + componentAttribute.Name + "' is already used by '" + descriptor.Type + "'"); } else { return; } } string typeName = type.AssemblyQualifiedName; if (descriptorTypeCache.ContainsKey(typeName)) { return; } ComponentDescriptor componentDescriptor = new ComponentDescriptor(type, componentAttribute); descriptorTypeCache[typeName] = componentDescriptor; descriptorNameCache[componentAttribute.Name] = componentDescriptor; } }
/// <summary> /// Creates an instance of a component and caches if it is of Singletone scope. /// </summary> /// <param name="component"></param> /// <returns></returns> internal object GetInstance(ComponentDescriptor component) { object response = null; if (!singletonsByName.TryGetValue(component.Attributes.Name, out response)) { response = Activator.CreateInstance(component.Type); if (component.Attributes.Scope == ComponentScope.Context) { singletonsByName[component.Attributes.Name] = response; Type currentType = component.Type; while (currentType != null) { HashSet <object> singletonTypes = null; if (!singletonsByType.TryGetValue(currentType.AssemblyQualifiedName, out singletonTypes)) { singletonTypes = new HashSet <object>(); singletonsByType[currentType.AssemblyQualifiedName] = singletonTypes; } singletonTypes.Add(response); currentType = currentType.BaseType; } } foreach (InjectDescriptor inject in component.Injections) { object injectionValue = null; foreach (IInjectionProvider injectionProvider in injectionProviders) { injectionValue = injectionProvider.ResolveInject(this, component, inject); if (injectionValue != null) { break; } } if (injectionValue == null) { throw new ComponentNotFoundException(inject.Attributes.Type, inject.Attributes.Name); } if (inject.Member is FieldInfo) { ((FieldInfo)inject.Member).SetValue(response, injectionValue); } else if (inject.Member is PropertyInfo) { ((PropertyInfo)inject.Member).SetValue(response, injectionValue); } } foreach (IComponentLifecycleProcessor componentLifecycleProcessor in componentLifecycleProcessors) { componentLifecycleProcessor.OnStart(this, response, component); } } return(response); }