예제 #1
0
        internal static void SetDiagnosticPolicies(UnityContainer container)
        {
            // Default policies
            container.ContextExecutePlan = UnityContainer.ContextValidatingExecutePlan;
            container.ContextResolvePlan = UnityContainer.ContextValidatingResolvePlan;
            container.ExecutePlan        = container.ExecuteValidatingPlan;

            // Processors
            var fieldsProcessor      = new FieldDiagnostic(container.Defaults);
            var methodsProcessor     = new MethodDiagnostic(container.Defaults, container);
            var propertiesProcessor  = new PropertyDiagnostic(container.Defaults);
            var constructorProcessor = new ConstructorDiagnostic(container.Defaults, container);

            // Processors chain
            container._processors = new StagedStrategyChain <MemberProcessor, BuilderStage>
            {
                { constructorProcessor, BuilderStage.Creation },
                { fieldsProcessor, BuilderStage.Fields },
                { propertiesProcessor, BuilderStage.Properties },
                { methodsProcessor, BuilderStage.Methods }
            };

            // Caches
            container._processors.Invalidated += (s, e) => container._processorsChain = container._processors.ToArray();
            container._processorsChain         = container._processors.ToArray();

            container.Defaults.ResolveDelegateFactory = container._buildStrategy;
            container.Defaults.FieldsSelector         = fieldsProcessor;
            container.Defaults.MethodsSelector        = methodsProcessor;
            container.Defaults.PropertiesSelector     = propertiesProcessor;
            container.Defaults.CtorSelector           = constructorProcessor;

            var validators = new ImplicitRegistration();

            validators.Set(typeof(Func <Type, InjectionMember, ConstructorInfo>), Validating.ConstructorSelector);
            validators.Set(typeof(Func <Type, InjectionMember, MethodInfo>), Validating.MethodSelector);
            validators.Set(typeof(Func <Type, InjectionMember, FieldInfo>), Validating.FieldSelector);
            validators.Set(typeof(Func <Type, InjectionMember, PropertyInfo>), Validating.PropertySelector);

            container._validators = validators;

            // Registration Validator
            container.TypeValidator = (typeFrom, typeTo) =>
            {
#if NETSTANDARD1_0 || NETCOREAPP1_0
                if (typeFrom != null && !typeFrom.GetTypeInfo().IsGenericType&& !typeTo.GetTypeInfo().IsGenericType&&
                    !typeFrom.GetTypeInfo().IsAssignableFrom(typeTo.GetTypeInfo()))
#else
                if (typeFrom != null && !typeFrom.IsGenericType && !typeTo.IsGenericType &&
                    !typeFrom.IsAssignableFrom(typeTo))
#endif
                {
                    throw new ArgumentException($"The type {typeTo} cannot be assigned to variables of type {typeFrom}.");
                }
            };
        }
        internal static void SetDiagnosticPolicies(UnityContainer container)
        {
            // Default policies
            container.ContextExecutePlan = UnityContainer.ContextValidatingExecutePlan;
            container.ContextResolvePlan = UnityContainer.ContextValidatingResolvePlan;
            container.ExecutePlan        = container.ExecuteValidatingPlan;
            container.Defaults           = new InternalRegistration(typeof(BuilderContext.ExecutePlanDelegate), container.ContextExecutePlan);
            if (null != container._registrations)
            {
                container.Set(null, null, container.Defaults);
            }

            // Processors
            var fieldsProcessor      = new FieldDiagnostic(container.Defaults);
            var methodsProcessor     = new MethodDiagnostic(container.Defaults, container);
            var propertiesProcessor  = new PropertyDiagnostic(container.Defaults);
            var constructorProcessor = new ConstructorDiagnostic(container.Defaults, container);

            // Processors chain
            container._processors = new StagedStrategyChain <MemberProcessor, BuilderStage>
            {
                { constructorProcessor, BuilderStage.Creation },
                { fieldsProcessor, BuilderStage.Fields },
                { propertiesProcessor, BuilderStage.Properties },
                { methodsProcessor, BuilderStage.Methods }
            };

            // Caches
            container._processors.Invalidated += (s, e) => container._processorsChain = container._processors.ToArray();
            container._processorsChain         = container._processors.ToArray();

            container.Defaults.Set(typeof(ResolveDelegateFactory), container._buildStrategy);
            container.Defaults.Set(typeof(ISelect <ConstructorInfo>), constructorProcessor);
            container.Defaults.Set(typeof(ISelect <FieldInfo>), fieldsProcessor);
            container.Defaults.Set(typeof(ISelect <PropertyInfo>), propertiesProcessor);
            container.Defaults.Set(typeof(ISelect <MethodInfo>), methodsProcessor);

            var validators = new InternalRegistration();

            validators.Set(typeof(Func <Type, InjectionMember, ConstructorInfo>), Validating.ConstructorSelector);
            validators.Set(typeof(Func <Type, InjectionMember, MethodInfo>), Validating.MethodSelector);
            validators.Set(typeof(Func <Type, InjectionMember, FieldInfo>), Validating.FieldSelector);
            validators.Set(typeof(Func <Type, InjectionMember, PropertyInfo>), Validating.PropertySelector);

            container._validators = validators;

            // Registration Validator
            container.TypeValidator = (typeFrom, typeTo) =>
            {
#if NETSTANDARD1_0 || NETCOREAPP1_0
                var infoFrom = typeFrom.GetTypeInfo();
                var infoTo   = typeTo.GetTypeInfo();

                if (null != typeFrom && typeFrom != null && !infoFrom.IsGenericType &&
                    null != typeTo && !infoTo.IsGenericType && !infoFrom.IsAssignableFrom(infoTo))
#else
                if (null != typeFrom && typeFrom != null && !typeFrom.IsGenericType &&
                    null != typeTo && !typeTo.IsGenericType && !typeFrom.IsAssignableFrom(typeTo))
#endif
                {
                    throw new ArgumentException($"The type {typeTo} cannot be assigned to variables of type {typeFrom}.");
                }

#if NETSTANDARD1_0 || NETCOREAPP1_0
                if (null != typeFrom && null != typeTo && infoFrom.IsGenericType && infoTo.IsArray &&
                    infoFrom.GetGenericTypeDefinition() == typeof(IEnumerable <>))
#else
                if (null != typeFrom && null != typeTo && typeFrom.IsGenericType && typeTo.IsArray &&
                    typeFrom.GetGenericTypeDefinition() == typeof(IEnumerable <>))
#endif
                { throw new ArgumentException($"Type mapping of IEnumerable<T> to array T[] is not supported."); }


#if NETSTANDARD1_0 || NETCOREAPP1_0
                if (null == typeFrom && infoTo.IsInterface)
#else
                if (null == typeFrom && typeTo.IsInterface)
#endif
                { throw new ArgumentException($"The type {typeTo} is an interface and can not be constructed."); }
            };

            if (null != container._registrations)
            {
                container.Set(null, null, container.Defaults);
            }
        }