コード例 #1
0
        public object Resolve(Type type, string name, InternalRegistration registration)
        {
            unsafe
            {
                var thisContext           = this;
                var containerRegistration = registration as ContainerRegistration;
                var container             = registration.Get(typeof(LifetimeManager)) is ContainerControlledLifetimeManager manager
                              ? ((UnityContainer)manager.Scope).LifetimeContainer
                              : Lifetime;

                var context = new BuilderContext
                {
                    Lifetime         = container,
                    Registration     = registration,
                    RegistrationType = type,
                    Name             = name,
                    Type             = null != containerRegistration ? containerRegistration.Type : type,
                    ExecutePlan      = ExecutePlan,
                    ResolvePlan      = ResolvePlan,
                    List             = List,
                    Overrides        = Overrides,
                    DeclaringType    = Type,
#if !NET40
                    Parent = new IntPtr(Unsafe.AsPointer(ref thisContext))
#endif
                };

                return(ExecutePlan(registration.BuildChain, ref context));
            }
        }
コード例 #2
0
        private IPolicySet CreateRegistration(Type type, Type policyInterface, object policy)
        {
            var registration = new InternalRegistration(policyInterface, policy);

            registration.BuildChain = GetBuilders(type, registration);
            return(registration);
        }
コード例 #3
0
 internal RegistrationContext(UnityContainer container, Type type, string name, InternalRegistration registration)
 {
     _registration = registration;
     _container    = container;
     _type         = type;
     _name         = name;
 }
コード例 #4
0
        private IPolicySet GetDefaultPolicies()
        {
            var defaults = new InternalRegistration(null, null);

            defaults.Set(typeof(IConstructorSelectorPolicy), new DefaultUnityConstructorSelectorPolicy());
            defaults.Set(typeof(IPropertySelectorPolicy), new DefaultUnityPropertySelectorPolicy());
            defaults.Set(typeof(IMethodSelectorPolicy), new DefaultUnityMethodSelectorPolicy());
            defaults.Set(typeof(IBuildPlanCreatorPolicy), new DynamicMethodBuildPlanCreatorPolicy(_buildPlanStrategies));

            return(defaults);
        }
コード例 #5
0
        private IPolicySet CreateAndSetOrUpdate(Type type, string name, InternalRegistration registration)
        {
            lock (GetRegistration)
            {
                if (null == _registrations)
                {
                    SetupChildContainerBehaviors();
                }
            }

            return(AddOrUpdate(type, name, registration));
        }
コード例 #6
0
        public void ShouldHandleCollisions()
        {
            var(s1, s2) = MakeCollision();

            var registrationSet = new RegistrationSet();
            var registration1   = new InternalRegistration();
            var registration2   = new InternalRegistration();
            var registration3   = new InternalRegistration();

            registrationSet.Add(typeof(IService), s1, registration1);
            Assert.AreEqual(1, registrationSet.Count);
            registrationSet.Add(typeof(IService), s2, registration2);
            Assert.AreEqual(2, registrationSet.Count);
            registrationSet.Add(typeof(IService), s1, registration3);
            Assert.AreEqual(2, registrationSet.Count);
        }
コード例 #7
0
        public void ShouldHandleCollisions()
        {
            Tuple <string, string> s = MakeCollision();

            var registrationSet = new RegistrationSet();
            var registration1   = new InternalRegistration();
            var registration2   = new InternalRegistration();
            var registration3   = new InternalRegistration();

            registrationSet.Add(typeof(IService), s.Item1, registration1);
            Assert.AreEqual(1, registrationSet.Count);
            registrationSet.Add(typeof(IService), s.Item2, registration2);
            Assert.AreEqual(2, registrationSet.Count);
            registrationSet.Add(typeof(IService), s.Item1, registration3);
            Assert.AreEqual(2, registrationSet.Count);
        }
コード例 #8
0
        private IPolicySet CreateRegistration(Type type, string name)
        {
            var registration = new InternalRegistration(type, name);

            if (type.GetTypeInfo().IsGenericType)
            {
                var factory = (InternalRegistration)_get(type.GetGenericTypeDefinition(), name);
                if (null != factory)
                {
                    registration.InjectionMembers = factory.InjectionMembers;
                    registration.Map = factory.Map;
                }
            }

            registration.BuildChain = GetBuilders(type, registration);
            return(registration);
        }
コード例 #9
0
        public override void PreBuildUp(IBuilderContext context)
        {
            ContainerRegistration containerRegistration = context.Registration as ContainerRegistration;
            InternalRegistration  internalRegistration  = context.Registration as InternalRegistration;

            if (containerRegistration != null)
            {
                _log.Info($"Building {containerRegistration.RegisteredType.FullName} mapped to {containerRegistration.MappedToType.FullName}");
            }
            else if (internalRegistration != null)
            {
                _log.Info($"Building {internalRegistration.Type.FullName}");
            }
            else
            {
                _log.Info($"Building {context.BuildKey.Type.FullName}");
            }
        }
コード例 #10
0
        private IPolicySet CreateRegistration(Type type, string name, InternalRegistration factory)
        {
            var registration = new InternalRegistration(type, name);

            if (null != factory)
            {
                registration.InjectionMembers = factory.InjectionMembers;
                registration.Map = factory.Map;
                var lifetime = factory.Get(typeof(LifetimeManager));
                if (lifetime is IFactoryLifetimeManager ManagerFactory)
                {
                    var manager = ManagerFactory.CreateLifetimePolicy();
                    registration.Set(typeof(LifetimeManager), manager);
                }
            }

            registration.BuildChain = GetBuilders(type, registration);
            return(registration);
        }
コード例 #11
0
ファイル: BuilderContext.cs プロジェクト: alser/container
        public object Resolve(Type type, string name, InternalRegistration registration)
        {
            unsafe
            {
                var thisContext = this;
                var context     = new BuilderContext
                {
                    Lifetime         = Lifetime,
                    Registration     = registration,
                    RegistrationType = type,
                    Name             = name,
                    Type             = registration is ContainerRegistration containerRegistration ? containerRegistration.Type : type,
                    ExecutePlan      = ExecutePlan,
                    List             = List,
                    Overrides        = Overrides,
                    DeclaringType    = Type,
#if !NET40
                    Parent = new IntPtr(Unsafe.AsPointer(ref thisContext))
#endif
                };

                return(ExecutePlan(registration.BuildChain, ref context));
            }
        }
コード例 #12
0
        public override bool RequiredToBuildType(IUnityContainer container, Type type, InternalRegistration registration, params InjectionMember[] injectionMembers)
        {
            if (registration is ContainerRegistration containerRegistration)
            {
                if (type != containerRegistration.Type ||
#pragma warning disable CS0618 // TODO: InjectionFactory
                    null != injectionMembers && injectionMembers.Any(i => i is InjectionFactory))
#pragma warning restore CS0618
                {
                    return(false);
                }
            }
#if NETSTANDARD1_0 || NETCOREAPP1_0
            return(type.GetTypeInfo().IsGenericType&& typeof(IEnumerable <>) == type.GetGenericTypeDefinition());
#else
            return(type.IsGenericType && typeof(IEnumerable <>) == type.GetGenericTypeDefinition());
#endif
        }
コード例 #13
0
 /// <summary>
 /// Analyze registered type
 /// </summary>
 /// <param name="container">Reference to hosting container</param>
 /// <param name="type"></param>
 /// <param name="registration">Reference to registration</param>
 /// <param name="injectionMembers"></param>
 /// <returns>Returns true if this strategy will participate in building of registered type</returns>
 public virtual bool RequiredToBuildType(IUnityContainer container, Type type, InternalRegistration registration, params InjectionMember[] injectionMembers)
 {
     return(true);
 }
コード例 #14
0
 private BuilderStrategy[] GetBuilders(Type type, InternalRegistration registration)
 {
     return(_strategiesChain.ToArray()
            .Where(strategy => strategy.RequiredToBuildType(this, type, registration, null))
            .ToArray());
 }
コード例 #15
0
 /// <summary>
 /// Analyzes registered type
 /// </summary>
 /// <param name="container">Reference to hosting container</param>
 /// <param name="registration">Reference to registration</param>
 /// <returns>Returns true if this strategy will participate in building of registered type</returns>
 public virtual bool RequiredToResolveInstance(IUnityContainer container, InternalRegistration registration)
 {
     return(false);
 }
コード例 #16
0
 public override bool RequiredToResolveInstance(IUnityContainer container, InternalRegistration registration) => true;
コード例 #17
0
        public override bool RequiredToBuildType(IUnityContainer container, Type type, InternalRegistration registration, params InjectionMember[] injectionMembers)
        {
            var policy = registration.Get(typeof(LifetimeManager));

            if (null != policy)
            {
                return(policy is TransientLifetimeManager ? false : true);
            }

            // Dynamic registration
#if NETSTANDARD1_0 || NETCOREAPP1_0
            if (!(registration is ContainerRegistration) && null != type && type.GetTypeInfo().IsGenericType)
            {
                return(true);
            }
#else
            if (!(registration is ContainerRegistration) && null != type && type.IsGenericType)
            {
                return(true);
            }
#endif
            return(false);
        }
コード例 #18
0
        /// <summary>
        /// Gets or sets policy for specified named type
        /// </summary>
        /// <remarks>
        /// This call never fails. If type or name is not present this method crates
        /// empty <see cref="InternalRegistration"/> object and initializes it with policy
        /// </remarks>
        /// <param name="type"></param>
        /// <param name="name"></param>
        /// <param name="interfaceType"></param>
        /// <returns></returns>
        private IBuilderPolicy this[Type type, string name, Type interfaceType]
        {
            get
            {
                var collisions   = 0;
                var hashCode     = (type?.GetHashCode() ?? 0) & 0x7FFFFFFF;
                var targetBucket = hashCode % _registrations.Buckets.Length;
                IMap <Type, IBuilderPolicy> registration = null;
                lock (_syncRoot)
                {
                    for (var i = _registrations.Buckets[targetBucket]; i >= 0; i = _registrations.Entries[i].Next)
                    {
                        if (_registrations.Entries[i].HashCode != hashCode ||
                            _registrations.Entries[i].Key != type)
                        {
                            collisions++;
                            continue;
                        }

                        var existing = _registrations.Entries[i].Value;
                        if (existing.RequireToGrow)
                        {
                            existing = existing is HashRegistry <string, IMap <Type, IBuilderPolicy> > registry
                                     ? new HashRegistry <string, IMap <Type, IBuilderPolicy> >(registry)
                                     : new HashRegistry <string, IMap <Type, IBuilderPolicy> >(LinkedRegistry.ListToHashCutoverPoint * 2,
                                                                                               (LinkedRegistry)existing);

                            _registrations.Entries[i].Value = existing;
                        }

                        registration = existing.GetOrAdd(name, () => new InternalRegistration(type, name));
                        break;
                    }

                    if (null == registration)
                    {
                        if (_registrations.RequireToGrow || ListToHashCutoverPoint < collisions)
                        {
                            _registrations = new HashRegistry <Type, IRegistry <string, IMap <Type, IBuilderPolicy> > >(_registrations);
                            targetBucket   = hashCode % _registrations.Buckets.Length;
                        }

                        registration = new InternalRegistration(type, name);
                        _registrations.Entries[_registrations.Count].HashCode = hashCode;
                        _registrations.Entries[_registrations.Count].Next     = _registrations.Buckets[targetBucket];
                        _registrations.Entries[_registrations.Count].Key      = type;
                        _registrations.Entries[_registrations.Count].Value    = new LinkedRegistry {
                            [name] = registration
                        };
                        _registrations.Buckets[targetBucket] = _registrations.Count;
                        _registrations.Count++;
                    }
                }

                return(registration[interfaceType]);
            }
            set
            {
                var collisions   = 0;
                var hashCode     = (type?.GetHashCode() ?? 0) & 0x7FFFFFFF;
                var targetBucket = hashCode % _registrations.Buckets.Length;
                lock (_syncRoot)
                {
                    for (var i = _registrations.Buckets[targetBucket]; i >= 0; i = _registrations.Entries[i].Next)
                    {
                        if (_registrations.Entries[i].HashCode != hashCode ||
                            _registrations.Entries[i].Key != type)
                        {
                            collisions++;
                            continue;
                        }

                        var existing = _registrations.Entries[i].Value;
                        if (existing.RequireToGrow)
                        {
                            existing = existing is HashRegistry <string, IMap <Type, IBuilderPolicy> > registry
                                     ? new HashRegistry <string, IMap <Type, IBuilderPolicy> >(registry)
                                     : new HashRegistry <string, IMap <Type, IBuilderPolicy> >(LinkedRegistry.ListToHashCutoverPoint * 2,
                                                                                               (LinkedRegistry)existing);

                            _registrations.Entries[i].Value = existing;
                        }

                        existing.GetOrAdd(name, () => new InternalRegistration(type, name))[interfaceType] = value;
                        return;
                    }

                    if (_registrations.RequireToGrow || ListToHashCutoverPoint < collisions)
                    {
                        _registrations = new HashRegistry <Type, IRegistry <string, IMap <Type, IBuilderPolicy> > >(_registrations);
                        targetBucket   = hashCode % _registrations.Buckets.Length;
                    }

                    _registrations.Entries[_registrations.Count].HashCode = hashCode;
                    _registrations.Entries[_registrations.Count].Next     = _registrations.Buckets[targetBucket];
                    _registrations.Entries[_registrations.Count].Key      = type;
                    _registrations.Entries[_registrations.Count].Value    = new LinkedRegistry {
                        [name] = new InternalRegistration(type, name)
                        {
                            [interfaceType] = value
                        }
                    };
                    _registrations.Buckets[targetBucket] = _registrations.Count;
                    _registrations.Count++;
                }
            }
        }
コード例 #19
0
        public override bool RequiredToBuildType(IUnityContainer container, Type type, InternalRegistration registration, params InjectionMember[] injectionMembers)
        {
            // Require Re-Resolve if no injectors specified
            registration.BuildRequired = (injectionMembers?.Any(m => m.BuildRequired) ?? false) ||
                                         registration is ContainerRegistration cr && cr.LifetimeManager is PerResolveLifetimeManager;

            return(true);
        }
コード例 #20
0
        public override bool RequiredToBuildType(IUnityContainer container, Type type, InternalRegistration registration, params InjectionMember[] injectionMembers)
        {
            if (!(registration is ContainerRegistration containerRegistration))
            {
                return(null != registration.Map);
            }

            // Validate input
            if (null == containerRegistration.Type || type == containerRegistration.Type)
            {
                return(false);
            }

            // Set mapping policy
#if NETSTANDARD1_0 || NETCOREAPP1_0
            if (type.GetTypeInfo().IsGenericTypeDefinition&&
                containerRegistration.Type.GetTypeInfo().IsGenericTypeDefinition&&
                null == containerRegistration.Map)
#else
            if (type.IsGenericTypeDefinition && containerRegistration.Type.IsGenericTypeDefinition && null == containerRegistration.Map)
#endif
            {
                containerRegistration.Map = (Type t) =>
                {
#if NETSTANDARD1_0 || NETCOREAPP1_0 || NET40
                    var targetTypeInfo = t.GetTypeInfo();
#else
                    var targetTypeInfo = t;
#endif
                    if (targetTypeInfo.IsGenericTypeDefinition)
                    {
                        // No need to perform a mapping - the source type is an open generic
                        return(containerRegistration.Type);
                    }

                    if (targetTypeInfo.GenericTypeArguments.Length != containerRegistration.Type.GetTypeInfo().GenericTypeParameters.Length)
                    {
                        throw new ArgumentException("Invalid number of generic arguments in types: {registration.MappedToType} and {t}");
                    }

                    try
                    {
                        return(containerRegistration.Type.MakeGenericType(targetTypeInfo.GenericTypeArguments));
                    }
                    catch (ArgumentException ae)
                    {
                        throw new MakeGenericTypeFailedException(ae);
                    }
                };
            }

            return(true);
        }
コード例 #21
0
        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);
            }
        }
コード例 #22
0
        public override bool RequiredToBuildType(IUnityContainer container, Type type, InternalRegistration registration, params InjectionMember[] injectionMembers)
        {
            if (registration is ContainerRegistration containerRegistration)
            {
                if (type != containerRegistration.Type ||
#pragma warning disable CS0618 // TODO: InjectionFactory
                    null != injectionMembers && injectionMembers.Any(i => i is InjectionFactory))
#pragma warning restore CS0618
                {
                    return(false);
                }
            }

            return(null != type && type.IsArray && type.GetArrayRank() == 1);
        }