Example #1
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
            };
        }