コード例 #1
0
        public bool CanInfer(Type targetType)
        {
            if (targetType.IsClass)
            {
                return(RegisteredTypes.ContainsKey(targetType));
            }

            return(RegisteredTypes.Values.ToArray().Exists(x => x.Inference != null && x.Inference.Equals(targetType)));
        }
コード例 #2
0
ファイル: Container.cs プロジェクト: akavick/Helper
        public virtual object Resolve(Type abs)
        {
            abs = abs ?? throw new ArgumentNullException(nameof(abs));

            if (!RegisteredTypes.ContainsKey(abs))
            {
                throw new NotSupportedException(
                          $"Тип {abs.FullName} не зарегистрирован в контейнере.");
            }

            if (Singletons.TryGetValue(abs, out var singleton) && singleton != null)
            {
                return(singleton);
            }

            if (ScopedInstances.TryGetValue(abs, out var scoped) && scoped != null)
            {
                return(scoped);
            }

            var imp        = RegisteredTypes[abs];
            var ctorInfo   = imp.GetConstructors().Single();
            var parameters = ctorInfo.GetParameters();
            var args       = parameters.Select(p => Resolve(p.ParameterType)).ToArray();
            var instance   = Activator.CreateInstance(imp, args);

            if (Singletons.ContainsKey(abs))
            {
                Singletons[abs] = instance;
            }
            else if (ScopedInstances.ContainsKey(abs))
            {
                ScopedInstances[abs] = instance;
            }

            return(instance);
        }
コード例 #3
0
ファイル: Container.cs プロジェクト: akavick/Helper
        public virtual void RegisterTransient(Type abs, Type imp, bool rewrite = false)
        {
            abs = abs ?? throw new ArgumentNullException(nameof(abs));
            imp = imp ?? throw new ArgumentNullException(nameof(imp));

            if (!imp.IsClass)
            {
                throw new NotSupportedException(
                          $"Тип {imp.FullName} не является классом.");
            }

            if (!rewrite && RegisteredTypes.ContainsKey(abs))
            {
                throw new InvalidOperationException(
                          $"Тип {abs.FullName} уже зарегистрирован в контейнере.");
            }

            if (!abs.IsAssignableFrom(imp))
            {
                throw new InvalidOperationException(
                          $"Тип {imp.FullName} не может быть приведён к типу {abs.FullName}.");
            }

            var foundTypes = new List <Type>();

            if (!Singletons.ContainsKey(abs) && !ScopedInstances.ContainsKey(abs))
            {
                foundTypes.Add(abs);
            }

            if (!Singletons.ContainsKey(imp) && !ScopedInstances.ContainsKey(imp) && !foundTypes.Contains(imp))
            {
                foundTypes.Add(imp);
            }

            void CheckRecursion(Type type)
            {
                var ctors = type.GetConstructors();

                if (ctors.Length != 1)
                {
                    throw new NotSupportedException(
                              $"Неразрешимая зависимость: контейнер не может выбрать вызываемый конструктор для типа {type.FullName}.");
                }

                var constructorInfo = ctors.Single();

                var parameterTransientTypes = constructorInfo.GetParameters()
                                              .Select(p => p.ParameterType)
                                              .Except(Singletons.Keys)
                                              .Except(ScopedInstances.Keys)
                                              .Distinct()
                                              .ToArray();

                foreach (var parameterType in parameterTransientTypes)
                {
                    if (foundTypes.Contains(parameterType))
                    {
                        throw new NotSupportedException(
                                  $"Неразрешимая зависимость: циклическая зависимость для типа {type.FullName} в типе параметра {parameterType.FullName}.");
                    }

                    if (parameterType.IsClass)
                    {
                        CheckRecursion(parameterType);
                    }
                }

                foundTypes.AddRange(parameterTransientTypes);
            }

            CheckRecursion(imp);

            RegisteredTypes[abs] = imp;
        }