public object Create(IocServiceMetaData metaData, DependencyCheckNode node) { object instance; // don't need to think about abstract or interface, it already be processed by service provider if (metaData.ConstrctorMetaData.Constructor.IsDefaultConstructor)//default constructor,none parameter { instance = metaData.ConstrctorMetaData.Constructor.DefaultInvoker.Invoke(); } else { /* * check dependency loop */ var newNode = new DependencyCheckNode(node, metaData.RelatedType); var constructor = metaData.ConstrctorMetaData; var paramsInstances = new object[constructor.Parameters.Length]; // genearate construtor parameters instance for (int i = 0; i < paramsInstances.Length; i++) { if (constructor.Parameters[i].IsFromConfig)//config key { var type = constructor.Parameters[i].IsAbstract ? constructor.Parameters[i].Impl : constructor.Parameters[i].RelatedType; if (type == null) { type = IocServiceProvider.Instance.GetImplementation(metaData.RelatedType); if (type == null) { throw new ImplementationNotFoundException($""); } } paramsInstances[i] = _configProvider.GetConfig(type, constructor.Parameters[i].ConfigKey); } else if (constructor.Parameters[i].HasDefaultValue)//default value { paramsInstances[i] = constructor.Parameters[i].DefaultValue; } else if (constructor.Parameters[i].IsAbstract) //abstract or interface { if (constructor.Parameters[i].HasImpl) //instructed by implementation type { paramsInstances[i] = IocServiceProvider.Instance.GetService(constructor.Parameters[i].Impl, newNode); } else { var impl = _manager.GetImplementation(constructor.Parameters[i].RelatedType);//try find impl if (impl == null) { throw new ImplementationNotFoundException($"construct({constructor}),parameter({constructor.Parameters[i]}) "); } paramsInstances[i] = IocServiceProvider.Instance.GetService(impl, newNode); } } else if (constructor.Parameters[i].RelatedType.IsBaseType())//config base type default value { paramsInstances[i] = JasmineDefaultValueProvider.GetDefaultValue(constructor.Parameters[i].RelatedType); } else { paramsInstances[i] = IocServiceProvider.Instance.GetService(constructor.Parameters[i].RelatedType, newNode); } } instance = constructor.Constructor.Invoker.Invoke(paramsInstances); } // need wire properties if (metaData.Properties.Length != 0) { foreach (var item in metaData.Properties) { wireProperty(instance, item); } } // call init method if (metaData.HasInitMethod) { callInitMethod(instance, metaData.InitMethod); } // raise instance created event foreach (var item in _listeners) { item.Value.OnInstanceCreated(metaData, instance); } return(instance); }
internal object GetService(Type serviceType, DependencyCheckNode node) { /* * generate metadata ,if metadata has not been generated! */ if (!_metaDataManager.ContainsKey(serviceType)) { generateMetaData(serviceType); } _metaDataManager.TryGetValue(serviceType, out var metaData); if (metaData == null)//interface or abstrct class ,pregenerate, if find implementation,_interface map should add mapping { var impl = _metaDataManager.GetImplementation(serviceType); if (impl == null)//do not find implementation { throw new ImplementationNotFoundException(null); } /* * generate impl metadata */ if (!_metaDataManager.ContainsKey(impl)) { generateMetaData(impl); } _metaDataManager.TryGetValue(impl, out metaData); } /* * create instance and cache instance */ if (metaData.Scope == ServiceScope.Singleton) { if (!_singletons.TryGetValue(serviceType, out var instance)) { instance = _instanceCreator.Create(metaData, node); _singletons.TryAdd(serviceType, instance); } return(_singletons[serviceType]); } else if (metaData.Scope == ServiceScope.ProtoType) { if (!_singletons.TryGetValue(serviceType, out var instance)) { instance = _instanceCreator.Create(metaData, node); _singletons.TryAdd(serviceType, instance); } return(_singletons[serviceType]); } else { return(_instanceCreator.Create(metaData, node)); } }