示例#1
0
        // TODO: Put strings into the resources.
        //
        public static IFactoryDependencyHandler GetDefaultDependencyHandler(INewInstanceDependencyTarget target)
        {
            target.EnsureNotNull(nameof(target));
            //
            var dependencyInstanceType = target.TargetType?.Resolve();

            if (dependencyInstanceType is null)
            {
                throw
                    new ArgumentException(
                        message: $"Указанным аргументом не определен целевой тип зависимости (свойство '{nameof(target.TargetType)}').",
                        paramName: nameof(target));
            }
            else if (dependencyInstanceType.IsValueType())
            {
                throw
                    new ArgumentException(
                        message: $"Целевой тип, определенный указанным аргументом, не является ссылочным типом.{Environment.NewLine}\tЦелевой тип:{Environment.NewLine}{dependencyInstanceType.FmtStr().G().IndentLines2()}",
                        paramName: nameof(target));
            }
            //
            const int maxCtorSignatureArgsCount       = 5;
            var       dependencyInstanceCtorArgsTypes =
                target
                .ConstructorSignature
                .EmptyIfNull()
                .Take(maxCtorSignatureArgsCount + 1)
                .Select(locTypeReference => locTypeReference?.Resolve())
                .ToArray();
            int nullElementIndex;

            if (dependencyInstanceCtorArgsTypes.Length > maxCtorSignatureArgsCount)
            {
                throw
                    new ArgumentException(
                        message: $"Количество аргументов сигнатуры конструктора целевого типа зависимости (свойство '{nameof(INewInstanceDependencyTarget)}.{nameof(target.ConstructorSignature)}') превышает максимально допустимое '{maxCtorSignatureArgsCount:d}'.",
                        paramName: nameof(target));
            }
            else if ((nullElementIndex = dependencyInstanceCtorArgsTypes.IndexOf(i => i is null)) > -1)
            {
                throw
                    new ArgumentException(
                        message: $"Набор аргументов сигнатуры конструктора целевого типа зависимости (свойство '{nameof(INewInstanceDependencyTarget)}.{nameof(target.ConstructorSignature)}') недопустим. {FormatXResource(typeof(Array), "CanNotContainNull/NullAt", nullElementIndex.ToString("d"))}",
                        paramName: nameof(target));
            }
            //
            TypeTubple6 repositoryKey;

            switch (dependencyInstanceCtorArgsTypes.Length)
            {
            case 0:
                repositoryKey = new TypeTubple6(__EmptyType, __EmptyType, __EmptyType, __EmptyType, __EmptyType, dependencyInstanceType);
                break;

            case 1:
                repositoryKey = new TypeTubple6(__EmptyType, __EmptyType, __EmptyType, __EmptyType, dependencyInstanceCtorArgsTypes[0], dependencyInstanceType);
                break;

            case 2:
                repositoryKey = new TypeTubple6(__EmptyType, __EmptyType, __EmptyType, dependencyInstanceCtorArgsTypes[0], dependencyInstanceCtorArgsTypes[1], dependencyInstanceType);
                break;

            case 3:
                repositoryKey = new TypeTubple6(__EmptyType, __EmptyType, dependencyInstanceCtorArgsTypes[0], dependencyInstanceCtorArgsTypes[1], dependencyInstanceCtorArgsTypes[2], dependencyInstanceType);
                break;

            case 4:
                repositoryKey = new TypeTubple6(__EmptyType, dependencyInstanceCtorArgsTypes[0], dependencyInstanceCtorArgsTypes[1], dependencyInstanceCtorArgsTypes[2], dependencyInstanceCtorArgsTypes[3], dependencyInstanceType);
                break;

            default:
                repositoryKey = new TypeTubple6(dependencyInstanceCtorArgsTypes[0], dependencyInstanceCtorArgsTypes[1], dependencyInstanceCtorArgsTypes[2], dependencyInstanceCtorArgsTypes[3], dependencyInstanceCtorArgsTypes[4], dependencyInstanceType);
                break;
            }
            return
                (__DefaultHandlers
                 .GetOrAdd(
                     spinLock: __DefaultHandlersSpinLock,
                     key: repositoryKey,
                     factory: factory,
                     unclaimedValue: (locKey, locValue) => locValue?.Dispose())
                 .Value);

            //
            DisposableLazy <IFactoryDependencyHandler> factory(TypeTubple6 locKey)
            =>
            new DisposableLazy <IFactoryDependencyHandler>(
                factory:
                () => {
                // Проверить существование конструктора экземпляра зависимости.
                //
                dependencyInstanceType.EnsureInstantiation(argsTypes: dependencyInstanceCtorArgsTypes);
                //
                switch (dependencyInstanceCtorArgsTypes.Length)
                {
                case 0:
                    return
                    (ActivationUtilities
                     .RequireConstructor <IFactoryDependencyHandler>(
                         concreteType: typeof(CtorFactoryDependencyHandler <>).MakeGenericType(locKey.Item6))
                         ());

                case 1:
                    return
                    (ActivationUtilities
                     .RequireConstructor <IFactoryDependencyHandler>(
                         concreteType: typeof(CtorFactoryDependencyHandler <,>).MakeGenericType(locKey.Item5, locKey.Item6))
                         ());

                case 2:
                    return
                    (ActivationUtilities
                     .RequireConstructor <IFactoryDependencyHandler>(
                         concreteType: typeof(CtorFactoryDependencyHandler <, ,>).MakeGenericType(locKey.Item4, locKey.Item5, locKey.Item6))
                         ());

                case 3:
                    return
                    (ActivationUtilities
                     .RequireConstructor <IFactoryDependencyHandler>(
                         concreteType: typeof(CtorFactoryDependencyHandler <, , ,>).MakeGenericType(locKey.Item3, locKey.Item4, locKey.Item5, locKey.Item6))
                         ());

                case 4:
                    return
                    (ActivationUtilities
                     .RequireConstructor <IFactoryDependencyHandler>(
                         concreteType: typeof(CtorFactoryDependencyHandler <, , , ,>).MakeGenericType(locKey.Item2, locKey.Item3, locKey.Item4, locKey.Item5, locKey.Item6))
                         ());

                default:
                    return
                    (ActivationUtilities
                     .RequireConstructor <IFactoryDependencyHandler>(
                         concreteType: typeof(CtorFactoryDependencyHandler <, , , , ,>).MakeGenericType(locKey.Item1, locKey.Item2, locKey.Item3, locKey.Item4, locKey.Item5, locKey.Item6))
                         ());
                }
            },
                ownsValue: true);
        }
示例#2
0
 public NewInstanceDependencyTarget(INewInstanceDependencyTarget other, bool isReadOnly = false)
     : base(isReadOnly : isReadOnly)
 {
     _targetType           = other.TargetType;
     _constructorSignature = other.ConstructorSignature?.ToArray().AsReadOnlyCollection();
 }