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[] { })); }
/// <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[] { })); }
/// <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)); }
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); }
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; }
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); }
/// <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; } }
/// <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; }
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; }
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) { }
/// <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; } }
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[] { })); }
/// <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; } }
object IIxInstance.GetData(IxProviderNode providerNode) { throw new NotSupportedException(); }
void IIxInstance.SetData(IxProviderNode providerNode, object data) { throw new NotSupportedException(); }
public IxResolvePath ReRoot(IxProviderNode newRoot) { return(new IxResolvePath(newRoot, new[] { Root }.Concat(Path).ToArray())); }
object IIxInstance.GetData(IxProviderNode providerNode) { Critical.Assert(false, "This object not intendet to have children and children data."); return(null); }
void IIxInstance.SetData(IxProviderNode providerNode, [CanBeNull] object data) { Critical.Assert(false, "This object not intended to have children and children data."); }
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); }
public void RegisterChild(IxProviderNode child) { _nodes.Add(child); _nodesById.Add(child.Identifier, child); VisibleNodes[child.Identifier] = new IxResolvePath(this, new[] { child }); }