Exemplo n.º 1
0
        public IxPerResolveProvider(
            IxHost host,
            [CanBeNull] IxProviderNode parentNode,
            IxProviderNodeConfig config,
            [CanBeNull] IxInstanceFactory instanceFactory,
            IxVisibilityFilter exportFilter,
            IxVisibilityFilter exportToParentFilter,
            IxVisibilityFilter importFilter,
            IxScopeBinderDelegate scopeBinder,
            bool autoDisposeEnabled,
            IxDisposeHandlerDelegate disposeHandler)
            : base(
                host,
                parentNode,
                config,
                instanceFactory,
                exportFilter,
                exportToParentFilter,
                importFilter,
                scopeBinder,
                autoDisposeEnabled,
                disposeHandler)
        {
            VxArgs.NotNull(parentNode, nameof(parentNode));
            VxArgs.NotNull(instanceFactory, nameof(instanceFactory));

            // Adding self provided as default for children.
            VisibleNodes.Add(new IxIdentifier(Identifier.Type), new IxResolvePath(this, new IxProviderNode[] { }));
        }
Exemplo n.º 2
0
        /// <summary>
        /// Initializes a new instance of the <see cref="IxSingletonProvider"/> class.
        /// </summary>
        /// <param name="host">IndirectX host.</param>
        public IxSingletonProvider(
            IxHost host,
            IxProviderNode parentNode,
            IxStdProviderConfig config,
            IxInstanceFactory instanceFactory,
            IxVisibilityFilter exportFilter,
            IxVisibilityFilter exportToParentFilter,
            IxVisibilityFilter importFilter,
            IxScopeBinderDelegate scopeBinder)
            : base(
                host,
                parentNode,
                config,
                instanceFactory,
                exportFilter,
                exportToParentFilter,
                importFilter,
                scopeBinder,
                config.AutoDisposeEnabled,
                config.DisposeHandler)
        {
            if (parentNode == null)
            {
                throw new ArgumentNullException(nameof(parentNode));
            }

            if (instanceFactory == null)
            {
                throw new ArgumentNullException(nameof(instanceFactory));
            }

            // Adding self provided as default for children.
            VisibleNodes.Add(new IxIdentifier(Identifier.Type), new IxResolvePath(this, new IxProviderNode[] { }));
        }
Exemplo n.º 3
0
 /// <summary>
 /// Initializes a new instance of the <see cref="IxScopeInstance"/> class.
 /// </summary>
 /// <param name="providerNode">Owner provider.</param>
 /// <param name="parentInstance">Parent instance.</param>
 /// <param name="creatorTempLock">First temp lock for the creator of a new instance.</param>
 public IxScopeInstance(
     IxProviderNode providerNode,
     [CanBeNull] IIxInstance parentInstance,
     out IIxInstanceLock creatorTempLock)
     : base(providerNode, parentInstance, out creatorTempLock)
 {
     SetObjectCreationTask(new ValueTask <object>(providerNode));
 }
Exemplo n.º 4
0
            public object GetData(IxProviderNode providerNode)
            {
                Critical.CheckedAssert(providerNode != null, "providerNode != null");

                if (!Monitor.IsEntered(_originInstance.ProviderNode.Host.InstanceTreeSyncRoot))
                {
                    Critical.Assert(false, "Data manipulations should be performed under lock.");
                }

                _rootContext.ProvidersData.TryGetValue(providerNode, out object result);

                return(result);
            }
Exemplo n.º 5
0
            public IxSelfInstance(IxProviderNode providerNode, IIxSelf self)
            {
                if (providerNode == null)
                {
                    throw new ArgumentNullException(nameof(providerNode));
                }

                if (self == null)
                {
                    throw new ArgumentNullException(nameof(self));
                }

                ProviderNode = providerNode;
                Object       = self;
            }
Exemplo n.º 6
0
        public object GetData(IxProviderNode providerNode)
        {
            if (providerNode == null)
            {
                throw new ArgumentNullException(nameof(providerNode));
            }

            if (!Monitor.IsEntered(ProviderNode.Host.InstanceTreeSyncRoot))
            {
                Critical.Assert(false, "Data manipulations should be performed under lock.");
            }

            object result;

            ChildrenData.TryGetValue(providerNode, out result);

            return(result);
        }
Exemplo n.º 7
0
            /// <inheritdoc/>
            public void SetData(IxProviderNode providerNode, [CanBeNull] object data)
            {
                Critical.CheckedAssert(providerNode != null, "providerNode != null");

                if (!Monitor.IsEntered(_originInstance.ProviderNode.Host.InstanceTreeSyncRoot))
                {
                    Critical.Assert(false, "Data manipulations should be performed under tree lock.");
                }

                if (data == null)
                {
                    _rootContext.ProvidersData.Remove(providerNode);
                }
                else
                {
                    _rootContext.ProvidersData[providerNode] = data;
                }
            }
Exemplo n.º 8
0
        /// <summary>
        /// Initializes a new instance of the <see cref="IxInstance"/> class.
        /// </summary>
        /// <remarks>
        /// Instance creates in the "Half-instantiated state".
        /// </remarks>
        /// <param name="providerNode">Node that produces instance.</param>
        /// <param name="parentInstance">Direct parent instance.</param>
        /// <param name="creatorTempLock">First temp lock for the creator of a new instance.</param>
        public IxInstance(
            IxProviderNode providerNode,
            [CanBeNull] IIxInstance parentInstance,
            out IIxInstanceLock creatorTempLock)
            : base(providerNode.Host.InstanceTreeSyncRoot)
        {
            ProviderNode              = providerNode;
            _parentInstance           = parentInstance;
            _ownedLocks               = new ProcessableSet <IIxInstanceLock>();
            _locks                    = new ProcessableSet <IIxInstanceLock>();
            _childrenDisposeCompleted = new AwaitableEvent();
            if (parentInstance != null)
            {
                new IxInstanceChildLock(parentInstance, this);
            }

            creatorTempLock = new IxInstancePinLock(this);
            _initTempLock   = creatorTempLock;
        }
Exemplo n.º 9
0
        public IxResolvePath(IxProviderNode root, IReadOnlyList <IxProviderNode> path)
        {
            if (root == null)
            {
                throw new ArgumentNullException(nameof(root));
            }

            if (path == null)
            {
                throw new ArgumentNullException(nameof(path));
            }

            // If path is empty, this means that root itself provide dependency.
            ////if (!path.Any())
            ////{
            ////    throw new ArgumentException("Path should not be empty.");
            ////}
            Root = root;
            Path = path;
        }
Exemplo n.º 10
0
 public IxTransientScope(
     IxHost host,
     IxProviderNode parentNode,
     IxProviderNodeConfig config,
     IxInstanceFactory instanceFactory,
     IxVisibilityFilter exportFilter,
     IxVisibilityFilter exportToParentFilter,
     IxVisibilityFilter importFilter)
     : base(
         host,
         parentNode,
         config,
         instanceFactory,
         exportFilter,
         exportToParentFilter,
         importFilter,
         (a, b, c, d, e) => { throw new NotImplementedException(); },
         false,
         obj => TaskEx.CompletedTask)
 {
 }
Exemplo n.º 11
0
        /// <inheritdoc/>
        public void SetData(IxProviderNode providerNode, [CanBeNull] object data)
        {
            if (providerNode == null)
            {
                throw new ArgumentNullException(nameof(providerNode));
            }

            if (!Monitor.IsEntered(ProviderNode.Host.InstanceTreeSyncRoot))
            {
                Critical.Assert(false, "Data manipulations should be performed under tree lock.");
            }

            if (data == null)
            {
                ChildrenData.Remove(providerNode);
            }
            else
            {
                ChildrenData[providerNode] = data;
            }
        }
Exemplo n.º 12
0
 public IxScope(
     IxHost host,
     [CanBeNull] IxProviderNode parentNode,
     IxScopeConfig config,
     IxVisibilityFilter exportFilter,
     IxVisibilityFilter exportToParentFilter,
     IxVisibilityFilter importFilter)
     : base(
         host,
         parentNode,
         config,
         null,
         exportFilter,
         exportToParentFilter,
         importFilter,
         host.ScopeBinderBuilder.Delegate(new IxRegistrationScopeBindingConfig()),
         false,
         obj => TaskEx.CompletedTask)
 {
     // Adding self provided as default for children.
     VisibleNodes.Add(new IxIdentifier(Identifier.Type), new IxResolvePath(this, new IxProviderNode[] { }));
 }
Exemplo n.º 13
0
        /// <summary>
        /// Second initialization phase.
        /// </summary>
        /// <param name="config">Host configuration.</param>
        /// <returns>Async execution TPL task.</returns>
        public async Task Initialize(IIxHostConfig config)
        {
            var allConfigNodes = new HashSet <IIxProviderNodeConfig>();

            config.Nodes.Add(
                new IxStdProviderConfig
            {
                Identifier      = new IxIdentifier(typeof(IIxHost)),
                InstanceBuilder = new IxExistingInstanceFactoryConfig <IIxHost>(this),
                DisposeHandler  = obj => TaskEx.CompletedTask
            });

            Action <IIxProviderNodeConfig, IxProviderNode> buildNodeAction = null;

            buildNodeAction = (nodeConfig, parentNode) =>
            {
                if (!allConfigNodes.Add(nodeConfig))
                {
                    throw new InvalidOperationException(
                              "Configuration contains the same object multiple times. Currently it's not allowed to avoid visitor cycles.");
                }

                IxProviderNode node = ProviderNodeBuilder.Delegate(nodeConfig, parentNode);

                // parent node is null only for root scope.
                if (parentNode == null)
                {
                    _rootScope = (IxScope)node;
                }

                foreach (IIxProviderNodeConfig childConfig in nodeConfig.Nodes)
                {
                    buildNodeAction(childConfig, node);
                }
            };

            buildNodeAction(config, null);

            Action <IxProviderNode> importRegistrationsFromChildren = null;

            importRegistrationsFromChildren = node =>
            {
                foreach (IxProviderNode child in node.Nodes)
                {
                    importRegistrationsFromChildren(child);

                    // Applying export to parent filter
                    // while Blocking from exporting resolve pathes with zero-length.
                    foreach (KeyValuePair <IxIdentifier, IxResolvePath> kvp in
                             child.VisibleNodes.Where(
                                 x => child.ExportToParentFilter(x.Key) &&
                                 x.Value.Path.Any()))
                    {
                        if (node.VisibleNodes.ContainsKey(kvp.Key))
                        {
                            throw new InvalidOperationException("Export to parent node conflict.");
                        }

                        node.VisibleNodes.Add(kvp.Key, kvp.Value.ReRoot(node));
                    }
                }
            };

            importRegistrationsFromChildren(_rootScope);

            Action <IxProviderNode> exportRegistrationsToChildren = null;

            exportRegistrationsToChildren = node =>
            {
                KeyValuePair <IxIdentifier, IxResolvePath>[] registrationsToExport =
                    node.VisibleNodes.Where(x => node.ExportFilter(x.Key)).ToArray();

                if (!registrationsToExport.Any())
                {
                    return;
                }

                foreach (IxProviderNode child in node.Nodes)
                {
                    foreach (KeyValuePair <IxIdentifier, IxResolvePath> kvp in
                             registrationsToExport.Where(x => child.ImportFilter(x.Key)))
                    {
                        IxResolvePath resolvePath;
                        if (child.VisibleNodes.TryGetValue(kvp.Key, out resolvePath))
                        {
                            // Skipping self to children.
                            if (resolvePath.Path.Any())
                            {
                                // Direct cycle resolution replacement.
                                if (!resolvePath.Target.ParentReplacementNodes.ContainsKey(kvp.Key))
                                {
                                    resolvePath.Target.ParentReplacementNodes.Add(kvp.Key, kvp.Value);
                                }
                            }
                        }
                        else
                        {
                            child.VisibleNodes.Add(kvp.Key, kvp.Value);
                        }
                    }

                    exportRegistrationsToChildren(child);
                }
            };

            exportRegistrationsToChildren(_rootScope);

            _rootScopeInstance = _rootScope.GetRootInstance();
            var resolveContext = new IxResolveContext(_rootScopeInstance, null, new Dictionary <IxIdentifier, object>());

            using (IIxInstanceLock rootResolverLock = await Resolve(
                       _rootScopeInstance,
                       new IxIdentifier(typeof(IIxResolver)),
                       resolveContext,
                       null))
            {
                var resolver = (IxResolver)rootResolverLock.Target.Object;
                Critical.CheckedAssert(
                    resolver.ParentContext == null && resolver.ParentFrame == null,
                    "After resolve finished, resolver should not be bound to any context.");

                Resolver = resolver;
            }
        }
Exemplo n.º 14
0
 object IIxInstance.GetData(IxProviderNode providerNode)
 {
     throw new NotSupportedException();
 }
Exemplo n.º 15
0
 void IIxInstance.SetData(IxProviderNode providerNode, object data)
 {
     throw new NotSupportedException();
 }
Exemplo n.º 16
0
 public IxResolvePath ReRoot(IxProviderNode newRoot)
 {
     return(new IxResolvePath(newRoot, new[] { Root }.Concat(Path).ToArray()));
 }
Exemplo n.º 17
0
 object IIxInstance.GetData(IxProviderNode providerNode)
 {
     Critical.Assert(false, "This object not intendet to have children and children data.");
     return(null);
 }
Exemplo n.º 18
0
 void IIxInstance.SetData(IxProviderNode providerNode, [CanBeNull] object data)
 {
     Critical.Assert(false, "This object not intended to have children and children data.");
 }
Exemplo n.º 19
0
        public IxProviderNode(
            IxHost host,
            [CanBeNull] IxProviderNode parentNode,
            IxProviderNodeConfig config,
            [CanBeNull] IxInstanceFactory instanceFactory,
            IxVisibilityFilter exportFilter,
            IxVisibilityFilter exportToParentFilter,
            IxVisibilityFilter importFilter,
            IxScopeBinderDelegate scopeBinder,
            bool autoDisposeEnabled,
            IxDisposeHandlerDelegate disposeHandler)
        {
            if (host == null)
            {
                throw new ArgumentNullException(nameof(host));
            }

            if (exportFilter == null)
            {
                throw new ArgumentNullException(nameof(exportFilter));
            }

            if (exportToParentFilter == null)
            {
                throw new ArgumentNullException(nameof(exportToParentFilter));
            }

            if (importFilter == null)
            {
                throw new ArgumentNullException(nameof(importFilter));
            }

            if (scopeBinder == null)
            {
                throw new ArgumentNullException(nameof(scopeBinder));
            }

            if (disposeHandler == null)
            {
                throw new ArgumentNullException(nameof(disposeHandler));
            }

            _nodes     = new List <IxProviderNode>();
            _nodesById = new Dictionary <IxIdentifier, IxProviderNode>();

            Host       = host;
            ParentNode = parentNode;

            if (config.Identifier == null)
            {
                // ReSharper disable once NotResolvedInText
                throw new ArgumentNullException("config.Identifier");
            }

            Identifier           = (IxIdentifier)config.Identifier;
            InstanceFactory      = instanceFactory;
            ExportFilter         = exportFilter;
            ExportToParentFilter = exportToParentFilter;
            ImportFilter         = importFilter;
            ScopeBinder          = scopeBinder;
            AutoDisposeEnabled   = autoDisposeEnabled;
            DisposeHandler       = disposeHandler;

            ParentNode?.RegisterChild(this);
        }
Exemplo n.º 20
0
 public void RegisterChild(IxProviderNode child)
 {
     _nodes.Add(child);
     _nodesById.Add(child.Identifier, child);
     VisibleNodes[child.Identifier] = new IxResolvePath(this, new[] { child });
 }