예제 #1
0
        /// <summary>
        /// Create a default <see cref="UnityContainer"/>.
        /// </summary>
        public UnityContainer()
        {
            _root = this;

            // WithLifetime
            LifetimeContainer        = new LifetimeContainer(this);
            _typeLifetimeManager     = TransientLifetimeManager.Instance;
            _factoryLifetimeManager  = TransientLifetimeManager.Instance;
            _instanceLifetimeManager = new ContainerControlledLifetimeManager();

            // Registrations
            _registrations = new Registrations(ContainerInitialCapacity);

            // Context
            _context = new ContainerContext(this);

            // Methods
            _get = Get;
            _getGenericRegistration    = GetOrAddGeneric;
            _isExplicitlyRegistered    = IsExplicitlyRegisteredLocally;
            IsTypeExplicitlyRegistered = IsTypeTypeExplicitlyRegisteredLocally;

            GetRegistration = GetOrAdd;
            Register        = AddOrUpdate;
            GetPolicy       = Get;
            SetPolicy       = Set;
            ClearPolicy     = Clear;

            // Build Strategies
            _strategies = new StagedStrategyChain <BuilderStrategy, UnityBuildStage>
            {
                {   // Array
                    new ArrayResolveStrategy(
                        typeof(UnityContainer).GetTypeInfo().GetDeclaredMethod(nameof(ResolveArray)),
                        typeof(UnityContainer).GetTypeInfo().GetDeclaredMethod(nameof(ResolveGenericArray))),
                    UnityBuildStage.Enumerable
                },
                { new BuildKeyMappingStrategy(), UnityBuildStage.TypeMapping },   // Mapping
                { new LifetimeStrategy(), UnityBuildStage.Lifetime },             // WithLifetime
                { new BuildPlanStrategy(), UnityBuildStage.Creation }             // Build
            };

            // Update on change
            _strategies.Invalidated += OnStrategiesChanged;
            _strategiesChain         = _strategies.ToArray();


            // Default Policies and Strategies
            SetDefaultPolicies(this);

            Set(typeof(Func <>), All, typeof(LifetimeManager), new PerResolveLifetimeManager());
            Set(typeof(Func <>), All, typeof(ResolveDelegateFactory), (ResolveDelegateFactory)DeferredFuncResolverFactory.DeferredResolveDelegateFactory);
            Set(typeof(Lazy <>), All, typeof(ResolveDelegateFactory), (ResolveDelegateFactory)GenericLazyResolverFactory.GetResolver);
            Set(typeof(IEnumerable <>), All, typeof(ResolveDelegateFactory), EnumerableResolver.Factory);

            // Register this instance
            ((IUnityContainer)this).RegisterInstance(typeof(IUnityContainer), null, this, _containerManager);
        }
        /// <inheritdoc />
        IUnityContainer IUnityContainerAsync.RegisterInstance(IEnumerable <Type> interfaces, string name, object instance, IInstanceLifetimeManager lifetimeManager)
        {
            // Validate input
            // TODO: Move to diagnostic

            if (null == interfaces && null == instance)
            {
                throw new ArgumentNullException(nameof(interfaces));
            }

            // Validate lifetime manager
            if (null == lifetimeManager)
            {
                lifetimeManager = new ContainerControlledLifetimeManager();
            }
            if (((LifetimeManager)lifetimeManager).InUse)
            {
                throw new InvalidOperationException(LifetimeManagerInUse);
            }
            ((LifetimeManager)lifetimeManager).SetValue(instance, LifetimeContainer);

            // Create registration and add to appropriate storage
            var mappedToType = instance?.GetType();
            var container    = lifetimeManager is SingletonLifetimeManager ? _root : this;
            var registration = new ExplicitRegistration(mappedToType, (LifetimeManager)lifetimeManager);

            // If Disposable add to container's lifetime
            if (lifetimeManager is IDisposable manager)
            {
                container.LifetimeContainer.Add(manager);
            }

            // Register interfaces
            var replaced = container.AddOrReplaceRegistrations(interfaces, name, registration)
                           .ToArray();

            // Release replaced registrations
            if (0 != replaced.Length)
            {
                Task.Factory.StartNew(() =>
                {
                    foreach (ImplicitRegistration previous in replaced)
                    {
                        if (0 == previous.Release() && previous.LifetimeManager is IDisposable disposable)
                        {
                            // Dispose replaced lifetime manager
                            container.LifetimeContainer.Remove(disposable);
                            disposable.Dispose();
                        }
                    }
                });
            }

            return(this);
        }
예제 #3
0
        /// <inheritdoc />
        IUnityContainer IUnityContainer.RegisterInstance(Type type, string name, object instance, IInstanceLifetimeManager lifetimeManager)
        {
            var mappedToType = instance?.GetType();
            var typeFrom     = type ?? mappedToType;

            try
            {
                // Validate input
                if (null == instance)
                {
                    throw new ArgumentNullException(nameof(instance));
                }

                if (null == lifetimeManager)
                {
                    lifetimeManager = new ContainerControlledLifetimeManager();
                }
                if (((LifetimeManager)lifetimeManager).InUse)
                {
                    throw new InvalidOperationException(LifetimeManagerInUse);
                }
                ((LifetimeManager)lifetimeManager).SetValue(instance, LifetimeContainer);

                // Create registration and add to appropriate storage
                var container    = lifetimeManager is SingletonLifetimeManager ? _root : this;
                var registration = new ContainerRegistration(null, mappedToType, ((LifetimeManager)lifetimeManager));

                // Add or replace existing
                var previous = container.Register(typeFrom, name, registration);
                if (previous is ContainerRegistration old &&
                    old.LifetimeManager is IDisposable disposable)
                {
                    // Dispose replaced lifetime manager
                    container.LifetimeContainer.Remove(disposable);
                    disposable.Dispose();
                }

                // If Disposable add to container's lifetime
                if (lifetimeManager is IDisposable manager)
                {
                    container.LifetimeContainer.Add(manager);
                }

                // Check what strategies to run
                registration.BuildChain = _strategiesChain.ToArray()
                                          .Where(strategy => strategy.RequiredToResolveInstance(this, registration))
                                          .ToArray();
                // Raise event
                container.RegisteringInstance?.Invoke(this, new RegisterInstanceEventArgs(typeFrom, instance,
                                                                                          name, ((LifetimeManager)lifetimeManager)));
            }
            catch (Exception ex)
            {
                var parts = new List <string>();

                if (null != name)
                {
                    parts.Add($" '{name}'");
                }
                if (null != lifetimeManager && !(lifetimeManager is TransientLifetimeManager))
                {
                    parts.Add(lifetimeManager.ToString());
                }

                var message = $"Error in  RegisterInstance<{typeFrom?.Name}>({string.Join(", ", parts)})";
                throw new InvalidOperationException(message, ex);
            }

            return(this);
        }