Beispiel #1
0
        private void InitializeRootRegistry()
        {
            Register = AddOrReplace;

            // Create Registry and set Factory strategy
            _metadata = new Registry <Type, int[]>();
            _registry = new Registry <NamedType, IPolicySet>(new DefaultPolicies(OptimizingFactory));

            // Register Container as IUnityContainer & IUnityContainerAsync
            var container = new ExplicitRegistration(typeof(UnityContainer), _containerManager)
            {
                BuildChain = new[] { new LifetimeStrategy() }
            };

            // Built-In Features
            _registry.Set(typeof(IUnityContainer), null, container);
            _registry.Set(typeof(IUnityContainerAsync), null, container);

            // Func<> Factory
            var funcBuiltInFctory = new ImplicitRegistration();

            funcBuiltInFctory.Set(typeof(LifetimeManager), new PerResolveLifetimeManager());
            funcBuiltInFctory.Set(typeof(ResolveDelegateFactory), FuncResolver.Factory);
            _registry.Set(typeof(Func <>), funcBuiltInFctory);

            // Lazy<>
            _registry.Set(typeof(Lazy <>), new ImplicitRegistration(typeof(ResolveDelegateFactory), LazyResolver.Factory));

            // Enumerable
            _registry.Set(typeof(IEnumerable <>), new ImplicitRegistration(typeof(ResolveDelegateFactory), EnumerableResolver.Factory));
        }
        /// <inheritdoc />
        IUnityContainer IUnityContainerAsync.RegisterFactory(IEnumerable <Type> interfaces, string name, Func <IUnityContainer, Type, string, object> factory, IFactoryLifetimeManager lifetimeManager)
        {
            // Validate input
            // TODO: Move to diagnostic

            if (null == interfaces)
            {
                throw new ArgumentNullException(nameof(interfaces));
            }
            if (null == factory)
            {
                throw new ArgumentNullException(nameof(factory));
            }
            if (null == lifetimeManager)
            {
                lifetimeManager = TransientLifetimeManager.Instance;
            }
            if (((LifetimeManager)lifetimeManager).InUse)
            {
                throw new InvalidOperationException(LifetimeManagerInUse);
            }

            // Create registration and add to appropriate storage
            var container = lifetimeManager is SingletonLifetimeManager ? _root : this;

            // TODO: InjectionFactory
            #pragma warning disable CS0618
            var injectionFactory = new InjectionFactory(factory);
            #pragma warning restore CS0618

            var injectionMembers = new InjectionMember[] { injectionFactory };
            var registration     = new ExplicitRegistration(_validators, (LifetimeManager)lifetimeManager, injectionMembers);

            // Add Injection Members
            //injectionFactory.AddPolicies<BuilderContext, ContainerRegistration>(
            //    type, type, name, ref registration);

            // 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);
        }
Beispiel #3
0
        public PipelineBuilder(ExplicitRegistration registration, UnityContainer container, IEnumerable <Pipeline> pipelines)
        {
            Type             = registration.Type ?? typeof(object);
            Registration     = registration;
            ContainerContext = container.Context;

            Seed        = null;
            _enumerator = pipelines.GetEnumerator();
        }
        /// <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);
        }
Beispiel #5
0
        private ExplicitRegistration?AddOrReplace(Type type, string?name, ExplicitRegistration registration)
        {
            var collisions = 0;
            var key        = new HashKey(type, name);
            var metaKey    = new HashKey(type);

            Debug.Assert(null != _registry);
            Debug.Assert(null != _metadata);

            registration.AddRef();

            // Registry
            lock (_syncRegistry)
            {
                var targetBucket = key.HashCode % _registry.Buckets.Length;
                for (var i = _registry.Buckets[targetBucket]; i >= 0; i = _registry.Entries[i].Next)
                {
                    ref var candidate = ref _registry.Entries[i];
                    if (candidate.Key != key)
                    {
                        collisions++;
                        continue;
                    }

                    // Swap the registration
                    var existing = candidate.Policies as ExplicitRegistration;

                    if (null == existing)
                    {
                        candidate.IsExplicit = true;
                        registration.Add(candidate.Policies);
                    }
                    candidate.Policies     = registration;
                    candidate.Pipeline     = registration.Pipeline;
                    candidate.Registration = registration;

                    // Replaced registration
                    return(existing);
                }

                // Expand if required
                if (_registry.RequireToGrow || CollisionsCutPoint < collisions)
                {
                    _registry    = new Registry(_registry);
                    targetBucket = key.HashCode % _registry.Buckets.Length;
                }

                // Create new entry
                ref var entry = ref _registry.Entries[_registry.Count];
Beispiel #6
0
        public void Add(Type type, ExplicitRegistration registration)
        {
            var key            = new HashKey(type, registration.Name);
            var bucket         = key.HashCode % _buckets.Length;
            var collisionCount = 0;

            for (int i = _buckets[bucket]; --i >= 0; i = _entries[i].Next)
            {
                ref var entry = ref _entries[i];
                if (entry.Key == key)
                {
                    entry.Registration = registration;
                    return;
                }
                collisionCount++;
            }
Beispiel #7
0
        private ExplicitRegistration?InitAndAdd(Type type, string?name, ExplicitRegistration registration)
        {
            lock (_syncRegistry)
            {
                if (null == _registry)
                {
                    _registry = new Registry();
                }
                if (null == _metadata)
                {
                    _metadata = new Metadata();

                    Register = AddOrReplace;
                }
            }

            return(Register(type, name, registration));
        }
        // Pipeline from factory
        public PipelineBuilder(Type type, ExplicitRegistration factory, LifetimeManager manager, UnityContainer owner)
        {
            Type             = type;
            Seed             = factory.Pipeline;
            TypeConverter    = factory.BuildType;
            LifetimeManager  = manager;
            InjectionMembers = factory.InjectionMembers;

            Factory      = factory;
            Policies     = factory;
            Registration = null;

            IsMapping = null != factory.BuildType;
            // TODO: Move to registration
            BuildRequired = null != factory.InjectionMembers && factory.InjectionMembers.Any(m => m.BuildRequired);

            ContainerContext = owner.Context;

            Debug.Assert(null != factory.Processors);
            _enumerator = factory.Processors.GetEnumerator();
        }
        // Pipeline From Registration
        public PipelineBuilder(Type type, ExplicitRegistration registration)
        {
            Debug.Assert(null != registration.Type);

            Type             = type;
            TypeConverter    = null;
            LifetimeManager  = registration.LifetimeManager;
            InjectionMembers = registration.InjectionMembers;

            Factory      = null;
            Policies     = registration;
            Registration = registration;

            IsMapping     = null != registration.Type && type != registration.Type;
            BuildRequired = registration.BuildRequired;

            Seed = registration.Pipeline;

            ContainerContext = registration.Owner.Context;

            Debug.Assert(null != registration?.Processors);
            _enumerator = registration.Processors.GetEnumerator();
        }
        /// <inheritdoc />
        IUnityContainer IUnityContainer.RegisterInstance(Type type, string name, object instance, IInstanceLifetimeManager lifetimeManager)
        {
            var mappedToType   = instance?.GetType();
            var registeredType = type ?? mappedToType;

            try
            {
                // Validate input
                if (null == registeredType)
                {
                    throw new InvalidOperationException($"At least one of Type arguments '{nameof(type)}' or '{nameof(instance)}' must be not 'null'");
                }

                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 ExplicitRegistration(null, mappedToType, ((LifetimeManager)lifetimeManager));

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

                // Register type
                var previous = container.Register(registeredType, name, registration);

                // Allow reference adjustment and disposal
                if (null != previous && 0 == previous.Release() &&
                    previous.LifetimeManager is IDisposable disposable)
                {
                    // Dispose replaced lifetime manager
                    container.LifetimeContainer.Remove(disposable);
                    disposable.Dispose();
                }

                // Check what strategies to run
                registration.BuildChain = _strategiesChain.ToArray()
                                          .Where(strategy => strategy.RequiredToResolveInstance(this, registration))
                                          .ToArray();
                // Raise event
                container.RegisteringInstance?.Invoke(this, new RegisterInstanceEventArgs(registeredType, 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<{registeredType?.Name}>({string.Join(", ", parts)})";
                throw new InvalidOperationException(message, ex);
            }

            return(this);
        }
Beispiel #11
0
        /// <summary>
        /// Create a default <see cref="UnityContainer"/>.
        /// </summary>
        public UnityContainer(ModeFlags mode = ModeFlags.Optimized)
        {
            if (!mode.IsValid())
            {
                throw new ArgumentException("'Activated' and 'Diagnostic' flags are mutually exclusive.");
            }

            /////////////////////////////////////////////////////////////
            // Initialize Root
            _root             = this;
            ExecutionMode     = mode;
            LifetimeContainer = new LifetimeContainer(this);
            Register          = AddOrReplace;

            //Built-In Registrations

            // Defaults
            Defaults = new DefaultPolicies(this);

            // IUnityContainer, IUnityContainerAsync
            var container = new ExplicitRegistration(this, null, typeof(UnityContainer), new ContainerLifetimeManager())
            {
                Pipeline = (ref PipelineContext c) => c.Container
            };

            Debug.Assert(null != container.LifetimeManager);

            // Create Registries
            _metadata = new Metadata();
            _registry = new Registry(Defaults);
            _registry.Set(typeof(IUnityContainer), null, container);       // TODO: Remove redundancy
            _registry.Set(typeof(IUnityContainerAsync), null, container);
            _registry.Set(typeof(IUnityContainer), null, container.LifetimeManager.Pipeline);
            _registry.Set(typeof(IUnityContainerAsync), null, container.LifetimeManager.Pipeline);

            /////////////////////////////////////////////////////////////
            // Built-In Features

            var func = new PolicySet(this);

            _registry.Set(typeof(Func <>), func);
            func.Set(typeof(LifetimeManager), new PerResolveLifetimeManager());
            func.Set(typeof(TypeFactoryDelegate), FuncResolver.Factory);                                                              // Func<> Factory
            _registry.Set(typeof(Lazy <>), new PolicySet(this, typeof(TypeFactoryDelegate), LazyResolver.Factory));                   // Lazy<>
            _registry.Set(typeof(IEnumerable <>), new PolicySet(this, typeof(TypeFactoryDelegate), EnumerableResolver.Factory));      // Enumerable
            _registry.Set(typeof(IRegex <>), new PolicySet(this, typeof(TypeFactoryDelegate), RegExResolver.Factory));                // Regular Expression Enumerable


            /////////////////////////////////////////////////////////////
            // Pipelines

            var typeFactory = new TypeFactoryPipeline();
            var lifetime    = new LifetimePipeline();

            // Mode of operation
            if (ExecutionMode.IsDiagnostic())
            {
                /////////////////////////////////////////////////////////////
                // Setup Diagnostic mode

                var diagnostic = new DiagnosticPipeline();

                // Create Context
                Context = new ContainerContext(this,
                                               new StagedStrategyChain <Pipeline, Stage> // Type Build Pipeline
                {
                    { diagnostic, Stage.Diagnostic },
                    { typeFactory, Stage.Factory },
                    { new MappingDiagnostic(), Stage.TypeMapping },
                    { new ConstructorDiagnostic(this), Stage.Creation },
                    { new FieldDiagnostic(this), Stage.Fields },
                    { new PropertyDiagnostic(this), Stage.Properties },
                    { new MethodDiagnostic(this), Stage.Methods }
                },
                                               new StagedStrategyChain <Pipeline, Stage> // Factory Resolve Pipeline
                {
                    { diagnostic, Stage.Diagnostic },
                    { new FactoryPipeline(), Stage.Factory }
                },
                                               new StagedStrategyChain <Pipeline, Stage> // Instance Resolve Pipeline
                {
                    { diagnostic, Stage.Diagnostic },
                    { typeFactory, Stage.Factory }
                });

                // Build process
                DependencyResolvePipeline = ValidatingDependencyResolvePipeline;

                // Validators
                ValidateType       = DiagnosticValidateType;
                ValidateTypes      = DiagnosticValidateTypes;
                CreateErrorMessage = CreateDiagnosticMessage;
            }
            else
            {
                // Create Context
                Context = new ContainerContext(this,
                                               new StagedStrategyChain <Pipeline, Stage> // Type Build Pipeline
                {
                    { lifetime, Stage.Lifetime },
                    { typeFactory, Stage.Factory },
                    { new MappingPipeline(), Stage.TypeMapping },
                    { new ConstructorPipeline(this), Stage.Creation },
                    { new FieldPipeline(this), Stage.Fields },
                    { new PropertyPipeline(this), Stage.Properties },
                    { new MethodPipeline(this), Stage.Methods }
                },
                                               new StagedStrategyChain <Pipeline, Stage> // Factory Resolve Pipeline
                {
                    { lifetime, Stage.Lifetime },
                    { new FactoryPipeline(), Stage.Factory }
                },
                                               new StagedStrategyChain <Pipeline, Stage> // Instance Resolve Pipeline
                {
                    { typeFactory, Stage.Factory }
                });
            }


            /////////////////////////////////////////////////////////////
            // Build Mode

            var build = _root.ExecutionMode.BuildMode();

            PipelineFromRegistration = build switch
            {
                ModeFlags.Activated => PipelineFromRegistrationActivated,
                ModeFlags.Compiled => PipelineFromRegistrationCompiled,
                _ => (FromRegistration)PipelineFromRegistrationOptimized
            };

            PipelineFromUnregisteredType = build switch
            {
                ModeFlags.Activated => PipelineFromUnregisteredTypeActivated,
                ModeFlags.Compiled => PipelineFromUnregisteredTypeCompiled,
                _ => (FromUnregistered)PipelineFromUnregisteredTypeOptimized
            };

            PipelineFromOpenGeneric = build switch
            {
                ModeFlags.Activated => PipelineFromOpenGenericActivated,
                ModeFlags.Compiled => PipelineFromOpenGenericCompiled,
                _ => (FromOpenGeneric)PipelineFromOpenGenericOptimized
            };
        }
Beispiel #12
0
        /// <inheritdoc />
        public IUnityContainer RegisterFactory(Type type, string?name, Func <IUnityContainer, Type, string?, object?> factory, IFactoryLifetimeManager?lifetimeManager)
        {
            // Validate input
            if (null == type)
            {
                throw new ArgumentNullException(nameof(type));
            }
            if (null == factory)
            {
                throw new ArgumentNullException(nameof(factory));
            }

            // Lifetime Manager
            var manager = lifetimeManager as LifetimeManager ?? Context.FactoryLifetimeManager.CreateLifetimePolicy();

            if (manager.InUse)
            {
                throw new InvalidOperationException(LifetimeManagerInUse);
            }
            manager.InUse = true;

            // Target Container
            var container = manager is SingletonLifetimeManager ? _root : this;

            Debug.Assert(null != container);

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

            // Create registration
            var registration = new ExplicitRegistration(container, name, type, manager);

            // Factory resolver
            var resolver = lifetimeManager is PerResolveLifetimeManager
                ? (ResolveDelegate <BuilderContext>)((ref BuilderContext c) =>
            {
                c.Existing = factory(c.Container, c.Type, c.Name);
                c.Set(typeof(LifetimeManager), new InternalPerResolveLifetimeManager(c.Existing));
                return(c.Existing);
            })
                : ((ref BuilderContext c) => factory(c.Container, c.Type, c.Name));

            registration.Set(typeof(ResolveDelegate <BuilderContext>), resolver);

            // Register
            var previous = container.Register(type, name, registration);

            // Allow reference adjustment and disposal
            if (null != previous && 0 == previous.Release() &&
                previous.LifetimeManager is IDisposable disposable)
            {
                // Dispose replaced lifetime manager
                container.LifetimeContainer.Remove(disposable);
                disposable.Dispose();
            }

            // Check what strategies to run
            registration.Processors = Context.FactoryPipelineCache;

            // Raise event
            container.Registering?.Invoke(this, new RegisterEventArgs(type, type, name, manager));

            // Return Container
            return(this);
        }
        /// <inheritdoc />
        IUnityContainer IUnityContainer.RegisterType(Type typeFrom, Type typeTo, string name, ITypeLifetimeManager lifetimeManager, InjectionMember[] injectionMembers)
        {
            try
            {
                var mappedToType   = typeTo;
                var registeredType = typeFrom ?? typeTo;

                // Validate input
                if (null == typeTo)
                {
                    throw new ArgumentNullException(nameof(typeTo));
                }
                if (null == lifetimeManager)
                {
                    lifetimeManager = TransientLifetimeManager.Instance;
                }
                if (((LifetimeManager)lifetimeManager).InUse)
                {
                    throw new InvalidOperationException(LifetimeManagerInUse);
                }

                // Validate if they are assignable
                TypeValidator?.Invoke(typeFrom, typeTo);

                // Create registration and add to appropriate storage
                var container    = lifetimeManager is SingletonLifetimeManager ? _root : this;
                var registration = new ExplicitRegistration(_validators, typeTo, (LifetimeManager)lifetimeManager, injectionMembers);

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

                // Add or replace existing
                var previous = container.Register(registeredType, name, registration);

                // Allow reference adjustment and disposal
                if (null != previous && 0 == previous.Release() &&
                    previous.LifetimeManager is IDisposable disposable)
                {
                    // Dispose replaced lifetime manager
                    container.LifetimeContainer.Remove(disposable);
                    disposable.Dispose();
                }

                // Add Injection Members
                if (null != injectionMembers && injectionMembers.Length > 0)
                {
                    foreach (var member in injectionMembers)
                    {
                        member.AddPolicies <BuilderContext, ExplicitRegistration>(
                            registeredType, mappedToType, name, ref registration);
                    }
                }

                // Check what strategies to run
                registration.BuildChain = _strategiesChain.ToArray()
                                          .Where(strategy => strategy.RequiredToBuildType(this,
                                                                                          registeredType, registration, injectionMembers))
                                          .ToArray();
                // Raise event
                container.Registering?.Invoke(this, new RegisterEventArgs(registeredType,
                                                                          mappedToType,
                                                                          name,
                                                                          ((LifetimeManager)lifetimeManager)));
            }
            catch (Exception ex)
            {
                var builder = new StringBuilder();

                builder.AppendLine(ex.Message);
                builder.AppendLine();

                var parts    = new List <string>();
                var generics = null == typeFrom ? typeTo?.Name : $"{typeFrom?.Name},{typeTo?.Name}";
                if (null != name)
                {
                    parts.Add($" '{name}'");
                }
                if (null != lifetimeManager && !(lifetimeManager is TransientLifetimeManager))
                {
                    parts.Add(lifetimeManager.ToString());
                }
                if (null != injectionMembers && 0 != injectionMembers.Length)
                {
                    parts.Add(string.Join(" ,", injectionMembers.Select(m => m.ToString())));
                }

                builder.AppendLine($"  Error in:  RegisterType<{generics}>({string.Join(", ", parts)})");
                throw new InvalidOperationException(builder.ToString(), ex);
            }

            return(this);
        }
        /// <inheritdoc />
        public IUnityContainer RegisterFactory(Type type, string name, Func <IUnityContainer, Type, string, object> factory, IFactoryLifetimeManager lifetimeManager)
        {
            // Validate input
            if (null == type)
            {
                throw new ArgumentNullException(nameof(type));
            }
            if (null == factory)
            {
                throw new ArgumentNullException(nameof(factory));
            }
            if (null == lifetimeManager)
            {
                lifetimeManager = TransientLifetimeManager.Instance;
            }
            if (((LifetimeManager)lifetimeManager).InUse)
            {
                throw new InvalidOperationException(LifetimeManagerInUse);
            }

            // Create registration and add to appropriate storage
            var container = lifetimeManager is SingletonLifetimeManager ? _root : this;

#pragma warning disable CS0618 // TODO: InjectionFactory
            var injectionFactory = new InjectionFactory(factory);
#pragma warning restore CS0618
            var injectionMembers = new InjectionMember[] { injectionFactory };
            var registration     = new ExplicitRegistration(_validators, type, ((LifetimeManager)lifetimeManager), injectionMembers);

            // Add or replace existing
            var previous = container.Register(type, name, registration);

            // Allow reference adjustment and disposal
            if (null != previous && 0 == previous.Release() &&
                previous.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);
            }

            // Add Injection Members
            injectionFactory.AddPolicies <BuilderContext, ExplicitRegistration>(
                type, type, name, ref registration);

            // Check what strategies to run
            registration.BuildChain = _strategiesChain.ToArray()
                                      .Where(strategy => strategy.RequiredToBuildType(this,
                                                                                      type, registration, injectionMembers))
                                      .ToArray();
            // Raise event
            container.Registering?.Invoke(this, new RegisterEventArgs(type, type, name,
                                                                      ((LifetimeManager)lifetimeManager)));
            return(this);
        }
Beispiel #15
0
        /// <inheritdoc />
        IUnityContainer IUnityContainer.RegisterType(Type typeFrom, Type typeTo, string name, ITypeLifetimeManager lifetimeManager, InjectionMember[] injectionMembers)
        {
            // Validate input
            var registeredType = ValidateType(typeFrom, typeTo);

            try
            {
                // Lifetime Manager
                var manager = lifetimeManager as LifetimeManager ?? Context.TypeLifetimeManager.CreateLifetimePolicy();
                if (manager.InUse)
                {
                    throw new InvalidOperationException(LifetimeManagerInUse);
                }
                manager.InUse = true;

                // Create registration and add to appropriate storage
                var container = manager is SingletonLifetimeManager ? _root : this;
                Debug.Assert(null != container);

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

                // Add or replace existing
                var registration = new ExplicitRegistration(container, name, typeTo, manager, injectionMembers);
                var previous     = container.Register(registeredType, name, registration);

                // Allow reference adjustment and disposal
                if (null != previous && 0 == previous.Release() &&
                    previous.LifetimeManager is IDisposable disposable)
                {
                    // Dispose replaced lifetime manager
                    container.LifetimeContainer.Remove(disposable);
                    disposable.Dispose();
                }

                // Add Injection Members
                if (null != injectionMembers && injectionMembers.Length > 0)
                {
                    foreach (var member in injectionMembers)
                    {
                        member.AddPolicies <PipelineContext, ExplicitRegistration>(
                            registeredType, typeTo, name, ref registration);
                    }
                }

                // Check what strategies to run
                registration.Processors = Context.TypePipelineCache;

                // Raise event
                container.Registering?.Invoke(this, new RegisterEventArgs(registeredType,
                                                                          typeTo,
                                                                          name,
                                                                          manager));
            }
            catch (Exception ex)
            {
                var builder = new StringBuilder();

                builder.AppendLine(ex.Message);
                builder.AppendLine();

                var parts    = new List <string>();
                var generics = null == typeFrom ? typeTo?.Name : $"{typeFrom?.Name},{typeTo?.Name}";
                if (null != name)
                {
                    parts.Add($" '{name}'");
                }
                if (null != lifetimeManager && !(lifetimeManager is TransientLifetimeManager))
                {
                    parts.Add(lifetimeManager.ToString());
                }
                if (null != injectionMembers && 0 != injectionMembers.Length)
                {
                    parts.Add(string.Join(" ,", injectionMembers.Select(m => m.ToString())));
                }

                builder.AppendLine($"  Error in:  RegisterType<{generics}>({string.Join(", ", parts)})");
                throw new InvalidOperationException(builder.ToString(), ex);
            }

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

            // Validate input
            if (null == registeredType)
            {
                throw new InvalidOperationException($"At least one of Type arguments '{nameof(type)}' or '{nameof(instance)}' must be not 'null'");
            }

            try
            {
                // Lifetime Manager
                var manager = lifetimeManager as LifetimeManager ?? Context.InstanceLifetimeManager.CreateLifetimePolicy();
                if (manager.InUse)
                {
                    throw new InvalidOperationException(LifetimeManagerInUse);
                }

                manager.InUse = true;
                if (manager is ILifetimeManagerAsync managerAsync)
                {
                    managerAsync.SetResult(instance, LifetimeContainer);
                }
                else
                {
                    manager.SetValue(instance, LifetimeContainer);
                }

                // Create registration and add to appropriate storage
                var container = manager is SingletonLifetimeManager ? _root : this;
                Debug.Assert(null != container);

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

                // Register type
                var registration = new ExplicitRegistration(container, name, mappedToType ?? registeredType, manager);
                var previous     = container.Register(registeredType, name, registration);

                // Allow reference adjustment and disposal
                if (null != previous && 0 == previous.Release() &&
                    previous.LifetimeManager is IDisposable disposable)
                {
                    // Dispose replaced lifetime manager
                    container.LifetimeContainer.Remove(disposable);
                    disposable.Dispose();
                }

                // Check what strategies to run
                registration.Processors = Context.InstancePipelineCache;

                // Raise event
                container.RegisteringInstance?.Invoke(this, new RegisterInstanceEventArgs(registeredType, instance, name, manager));
            }
            catch (Exception ex)
            {
                var parts = new List <string>();

                if (null != name)
                {
                    parts.Add($" '{name}'");
                }
                var message = $"Error in  RegisterInstance<{registeredType?.Name}>({string.Join(", ", parts)})";
                throw new InvalidOperationException(message, ex);
            }

            return(this);
        }
        /// <inheritdoc />
        Task IUnityContainerAsync.RegisterFactory(IEnumerable <Type>?interfaces, string?name, Func <IUnityContainer, Type, string?, object?> factory, IFactoryLifetimeManager?lifetimeManager)
        {
            // Validate input
            if (null == interfaces)
            {
                throw new ArgumentNullException(nameof(interfaces));
            }
            if (null == factory)
            {
                throw new ArgumentNullException(nameof(factory));
            }

            return(Task.Factory.StartNew(() =>
            {
                // TODO: implementation required
                var type = interfaces.First();

                // Lifetime Manager
                var manager = lifetimeManager as LifetimeManager ?? Context.FactoryLifetimeManager.CreateLifetimePolicy();
                if (manager.InUse)
                {
                    throw new InvalidOperationException(LifetimeManagerInUse);
                }
                manager.InUse = true;

                // Target Container
                var container = manager is SingletonLifetimeManager ? _root : this;
                Debug.Assert(null != container);

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

                // Create registration
                var registration = new ExplicitRegistration(container, name, type, manager);

                // Factory resolver
                var resolver = lifetimeManager is PerResolveLifetimeManager
                    ? (ResolveDelegate <BuilderContext>)((ref BuilderContext c) =>
                {
                    c.Existing = factory(c.Container, c.Type, c.Name);
                    c.Set(typeof(LifetimeManager), new InternalPerResolveLifetimeManager(c.Existing));
                    return c.Existing;
                })
                    : ((ref BuilderContext c) => factory(c.Container, c.Type, c.Name));
                registration.Set(typeof(ResolveDelegate <BuilderContext>), resolver);

                // Build Pipeline
                PipelineBuilder builder = new PipelineBuilder(registration, container, Context.FactoryPipelineCache);
                registration.Pipeline = builder.Pipeline();

                // Register
                var previous = container.Register(type, name, registration);

                // Allow reference adjustment and disposal
                if (null != previous && 0 == previous.Release() &&
                    previous.LifetimeManager is IDisposable disposable)
                {
                    // Dispose replaced lifetime manager
                    container.LifetimeContainer.Remove(disposable);
                    disposable.Dispose();
                }

                // TODO: Raise event
                // container.Registering?.Invoke(this, new RegisterEventArgs(type, type, name, manager));
            }));
        }
        /// <inheritdoc />
        Task IUnityContainerAsync.RegisterType(IEnumerable <Type>?interfaces, Type type, string?name, ITypeLifetimeManager?lifetimeManager, params InjectionMember[] injectionMembers)
        {
            return(Task.Factory.StartNew((object status) =>
            {
                var types = status as Type[];

                Type?typeFrom = null;
                var registeredType = typeFrom ?? type;

                // Validate input
                //if (null == registeredType) throw new InvalidOperationException($"At least one of Type arguments '{nameof(typeFrom)}' or '{nameof(typeTo)}' must be not 'null'");

                try
                {
                    // Lifetime Manager
                    var manager = lifetimeManager as LifetimeManager ?? Context.TypeLifetimeManager.CreateLifetimePolicy();
                    if (manager.InUse)
                    {
                        throw new InvalidOperationException(LifetimeManagerInUse);
                    }
                    manager.InUse = true;

                    // Create registration and add to appropriate storage
                    var container = manager is SingletonLifetimeManager ? _root : this;
                    Debug.Assert(null != container);

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

                    // Add or replace existing
                    var registration = new ExplicitRegistration(container, name, type, manager, injectionMembers);
                    var previous = container.Register(registeredType, name, registration);

                    // Allow reference adjustment and disposal
                    if (null != previous && 0 == previous.Release() &&
                        previous.LifetimeManager is IDisposable disposable)
                    {
                        // Dispose replaced lifetime manager
                        container.LifetimeContainer.Remove(disposable);
                        disposable.Dispose();
                    }

                    // Add Injection Members
                    if (null != injectionMembers && injectionMembers.Length > 0)
                    {
                        foreach (var member in injectionMembers)
                        {
                            member.AddPolicies <BuilderContext, ExplicitRegistration>(
                                registeredType, type, name, ref registration);
                        }
                    }

                    // Check what strategies to run
                    registration.Processors = Context.TypePipelineCache;

                    // Raise event
                    //container.Registering?.Invoke(this, new RegisterEventArgs(registeredType,
                    //                                                          typeTo,
                    //                                                          name,
                    //                                                          manager));
                }
                catch (Exception ex)
                {
                    var builder = new StringBuilder();

                    builder.AppendLine(ex.Message);
                    builder.AppendLine();

                    var parts = new List <string>();
                    var generics = null == typeFrom ? type?.Name : $"{typeFrom?.Name},{type?.Name}";
                    if (null != name)
                    {
                        parts.Add($" '{name}'");
                    }
                    if (null != lifetimeManager && !(lifetimeManager is TransientLifetimeManager))
                    {
                        parts.Add(lifetimeManager.ToString());
                    }
                    if (null != injectionMembers && 0 != injectionMembers.Length)
                    {
                        parts.Add(string.Join(" ,", injectionMembers.Select(m => m.ToString())));
                    }

                    builder.AppendLine($"  Error in:  RegisterType<{generics}>({string.Join(", ", parts)})");
                    throw new InvalidOperationException(builder.ToString(), ex);
                }
            }, ValidateTypes(interfaces, type)));
        }
Beispiel #19
0
        private ResolveDelegate <PipelineContext> PipelineFromOpenGenericOptimized(ref HashKey key, ExplicitRegistration factory)
        {
            Debug.Assert(null != _registry);
            Debug.Assert(null != key.Type);

            LifetimeManager?manager = null;
            ResolveDelegate <PipelineContext>?pipeline = null;

            // Add Pipeline to the Registry
            lock (_syncRegistry)
            {
                bool adding       = true;
                var  collisions   = 0;
                var  targetBucket = key.HashCode % _registry.Buckets.Length;
                for (var i = _registry.Buckets[targetBucket]; i >= 0; i = _registry.Entries[i].Next)
                {
                    ref var candidate = ref _registry.Entries[i];
                    if (candidate.Key != key)
                    {
                        collisions++;
                        continue;
                    }

                    // Pipeline already been created
                    if (null != candidate.Pipeline)
                    {
                        return(candidate.Pipeline);
                    }

                    // Lifetime Manager
                    manager = Context.TypeLifetimeManager.CreateLifetimePolicy();
                    manager.PipelineDelegate = (ResolveDelegate <PipelineContext>)SpinWait;

                    // Type has not been registered
                    if (null == candidate.Registration)
                    {
                        candidate.Pipeline = manager.Pipeline;
                    }

                    adding = false;
                    break;
                }

                if (adding)
                {
                    // Expand if required
                    if (_registry.RequireToGrow || CollisionsCutPoint < collisions)
                    {
                        _registry    = new Registry(_registry);
                        targetBucket = key.HashCode % _registry.Buckets.Length;
                    }

                    // Lifetime Manager
                    manager = factory.LifetimeManager.CreateLifetimePolicy();
                    manager.PipelineDelegate = (ResolveDelegate <PipelineContext>)SpinWait;

                    // Create new entry
                    ref var entry = ref _registry.Entries[_registry.Count];
                    entry.Key      = key;
                    entry.Pipeline = manager.Pipeline;
                    entry.Next     = _registry.Buckets[targetBucket];
                    _registry.Buckets[targetBucket] = _registry.Count++;
                }
Beispiel #20
0
        private ResolveDelegate <PipelineContext> PipelineFromRegistrationOptimized(Type?type, ExplicitRegistration registration, int position)
        {
            Debug.Assert(null != _registry);
            Debug.Assert(null != type);

            var manager = registration.LifetimeManager;

            ResolveDelegate <PipelineContext>?pipeline = null;

            lock (_syncRegistry)
            {
                ref var entry = ref _registry.Entries[position];

                if (ReferenceEquals(entry.Registration, registration) && null == entry.Pipeline)
                {
                    entry.Pipeline           = manager.Pipeline;
                    manager.PipelineDelegate = (ResolveDelegate <PipelineContext>)SpinWait;
                }
            }
Beispiel #21
0
 public RegistrationWrapper(Type type, IPolicySet registration)
 {
     RegisteredType = type;
     _registration  = (ExplicitRegistration)registration;
 }