//Выбор действий в зависимости от Singleton или Instance private object GetObject(ImplementationInfo implInfo) { if (implInfo.lifeTime == LifeTime.Singleton) { if (!ImplementationInstances.ContainsKey(implInfo.ImplementationType)) { var impl = CreateObject(implInfo.ImplementationType); ImplementationInstances.TryAdd(implInfo.ImplementationType, impl); } //Возврат значения из словаря return(ImplementationInstances[implInfo.ImplementationType]); } else { //Создание нового объекта return(CreateObject(implInfo.ImplementationType)); } }
public void Register(Type tDependency, Type tImplementation, LifeTime lifetime) { if (tDependency.IsValueType) { throw new ArgumentException("TDependency must be a reference type"); } if (tImplementation.IsAbstract) { throw new ArgumentException("TImplementation can't be an abstract class"); } if (!tImplementation.GetConstructors(BindingFlags.Public | BindingFlags.Instance).Any()) { throw new ArgumentException("TImplementation doesn't have any public constructors"); } if (!tDependency.IsAssignableFrom(tImplementation) && !tDependency.IsGenericTypeDefinition) { throw new ArgumentException("TImplementation doesn't implement TDependency interface"); } //Если в словаре нет такого интерфейса, создаем запись и список if (!RegisteredDependencies.ContainsKey(tDependency)) { RegisteredDependencies.Add(tDependency, new List <ImplementationInfo>()); } if (RegisteredDependencies[tDependency].Find(item => item.ImplementationType == tImplementation) != null) { throw new ArgumentException("Such dependency is already registered"); } else { ImplementationInfo impl = new ImplementationInfo(tImplementation, lifetime); RegisteredDependencies[tDependency].Add(impl); } }
public object Resolve(Type DependencyType) { object resultObj = null; // Если в стеке уже встречался обьект с таким типом, то // объект получает значение по умолчанию (0 или null) if (!cycleStack.Contains(DependencyType)) { cycleStack.Push(DependencyType); List <ImplementationInfo> implInfos; // 1.IEnumerable<IService> services = provider.Resolve<IEnumerable<IService>>(); if (typeof(IEnumerable).IsAssignableFrom(DependencyType)) { Type actualDependency = DependencyType.GetGenericArguments()[0]; if (dependencyConfig.RegisteredDependencies.ContainsKey(actualDependency)) { implInfos = dependencyConfig.RegisteredDependencies[actualDependency]; int implCount = implInfos.Count; var array = Array.CreateInstance(actualDependency, implCount); for (int i = 0; i < implCount; i++) { array.SetValue(GetObject(implInfos[i]), i); } cycleStack.Pop(); return(array); } else { throw new KeyNotFoundException($"Dependency {actualDependency.Name} is not registered."); } } // 2.Open generic dependency //Если это дженерик и имплементация IService<> есть в словаре if (DependencyType.IsGenericType && dependencyConfig.RegisteredDependencies.ContainsKey(DependencyType.GetGenericTypeDefinition())) { //Получаем из IService<IRepos> -> IService' Type GenericType = DependencyType.GetGenericTypeDefinition(); //Вытягиваем реализацию ServiceImpl ImplementationInfo implInfo = dependencyConfig.RegisteredDependencies[GenericType].First(); //ServiceImpl<> -> ServiceImpl<IRepos> implInfo.ImplementationType = implInfo.ImplementationType.MakeGenericType(DependencyType.GetGenericArguments()[0]); object result = GetObject(implInfo); cycleStack.Pop(); return(result); } // 3.Simple Generic Dependency or SimpleDependency if (dependencyConfig.RegisteredDependencies.ContainsKey(DependencyType)) { implInfos = dependencyConfig.RegisteredDependencies[DependencyType]; object result = GetObject(implInfos.First()); cycleStack.Pop(); return(result); } else if (!dependencyConfig.RegisteredDependencies.ContainsKey(DependencyType)) { throw new KeyNotFoundException($"Dependency {DependencyType.Name} is not registered."); } } else { return(GetDefaultValue(DependencyType)); } return(resultObj); }