Ejemplo n.º 1
0
 public IxResolveFrame(
     [CanBeNull] IxResolveFrame parentFrame,
     IIxInstance instance)
 {
     ParentFrame = parentFrame;
     Instance    = instance;
 }
Ejemplo n.º 2
0
            public IxResolver(
                IxHost host,
                IIxInstance ownerInstance,
                [CanBeNull] IxResolveContext parentContext,
                [CanBeNull] IxResolveFrame parentFrame)
            {
                if (host == null)
                {
                    throw new ArgumentNullException(nameof(host));
                }

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

                if (parentFrame != null)
                {
                    if (parentContext == null)
                    {
                        throw new ArgumentNullException();
                    }
                }

                Host          = host;
                OwnerInstance = ownerInstance;
                ParentFrame   = parentFrame;
                ParentContext = parentContext;
            }
Ejemplo n.º 3
0
#pragma warning disable CS1998 // Async method lacks 'await' operators and will run synchronously

        /// <inheritdoc/>
        public override async ValueTask <IIxInstanceLock> GetInstance(
            IIxInstance parentInstance,
            IxIdentifier identifier,
            IxHost.IxResolveContext context,
            [CanBeNull] IxResolveFrame frame)
        {
            if (parentInstance == null)
            {
                throw new ArgumentNullException(nameof(parentInstance));
            }

            lock (Host.InstanceTreeSyncRoot)
            {
                IIxInstanceLock scopeLock;
                IxScopeInstance singleton;
                object          data = parentInstance.GetData(this);
                if (data == null)
                {
                    singleton = new IxScopeInstance(this, parentInstance, out scopeLock);
                    parentInstance.SetData(this, singleton);
                }
                else
                {
                    singleton = (IxScopeInstance)data;
                    scopeLock = new IxInstancePinLock(singleton);
                }

                return(scopeLock);
            }
        }
Ejemplo n.º 4
0
        /// <summary>
        /// Initializes a new instance of the <see cref="IxSingletonInstance"/> class.
        /// </summary>
        /// <param name="providerNode">Singleton provider.</param>
        /// <param name="parentInstance">Parent instance.</param>
        /// <param name="context">The resolve context.</param>
        /// <param name="frame">The resolution frame in the resolve sequence.</param>
        /// <param name="creatorTempLock">First temp lock for the creator of a new instance.</param>
        public IxSingletonInstance(
            IxSingletonProvider providerNode,
            IIxInstance parentInstance,
            IxHost.IxResolveContext context,
            [CanBeNull] IxResolveFrame frame,
            out IIxInstanceLock creatorTempLock)
            : base(providerNode, parentInstance, out creatorTempLock)
        {
            if (parentInstance == null)
            {
                throw new ArgumentNullException(nameof(parentInstance));
            }

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

            Debug.Assert(ProviderNode.InstanceFactory != null, "IxSingletonProvider always have instance factory.");

            var newFrame = new IxResolveFrame(frame, this);

            SetObjectCreationTask(
                ProviderNode.InstanceFactory.Factory(
                    this,
                    parentInstance,
                    context,
                    newFrame));
        }
Ejemplo n.º 5
0
        private async ValueTask <IIxInstanceLock> Resolve(
            IIxInstance originInstance,
            IxIdentifier identifier,
            IxResolveContext context,
            [CanBeNull] IxResolveFrame frame)
        {
            if (originInstance == null)
            {
                throw new ArgumentNullException(nameof(originInstance));
            }

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

            if (originInstance.ProviderNode.Host != this)
            {
                throw new InvalidOperationException("You cannot use resolver from different host.");
            }

            ////if (context.IsFailed)
            ////{
            ////    throw new InvalidOperationException("You cannot do anything inside failed resolve context.");
            ////}
            return(await ResolveHandler.Delegate(originInstance, identifier, context, frame));
        }
Ejemplo n.º 6
0
        /// <summary>
        /// Resolves list of <c>dependencies</c> from the specified origin. TODO: Implement <c>this</c> method with parallel
        /// resolution.
        /// </summary>
        /// <typeparam name="TResult">Target operation result type.</typeparam>
        /// <param name="originInstance">Origin instance. Where <c>dependencies</c> are queried.</param>
        /// <param name="dependencies">List of dependency identifiers.</param>
        /// <param name="context">Resolve <c>context</c>.</param>
        /// <param name="frame">The resolve sequence frame.</param>
        /// <param name="targetOperation">Operation that should be performed with resolved <c>dependencies</c>.</param>
        /// <returns>Result of target opration.</returns>
        public async ValueTask <TResult> ResolveList <TResult>(
            IIxInstance originInstance,
            HashSet <IxIdentifier> dependencies,
            IxResolveContext context,
            [CanBeNull] IxResolveFrame frame,
            Func <Dictionary <IxIdentifier, IIxInstance>, ValueTask <TResult> > targetOperation)
        {
            if (originInstance == null)
            {
                throw new ArgumentNullException(nameof(originInstance));
            }

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

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

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

            using (HashSet <IxIdentifier> .Enumerator enumerator = dependencies.GetEnumerator())
            {
                var result = new Dictionary <IxIdentifier, IIxInstance>();

                async ValueTask <TResult> ResolveItem()
                {
                    // ReSharper disable once AccessToDisposedClosure
                    if (!enumerator.MoveNext())
                    {
                        return(await targetOperation(result));
                    }

                    // ReSharper disable once AccessToDisposedClosure
                    IxIdentifier identifier = enumerator.Current;

                    using (IIxInstanceLock instanceLock = await Resolve(originInstance, identifier, context, frame))
                    {
                        result.Add(identifier, instanceLock.Target);
                        TResult resultItem = await ResolveItem();

                        if (identifier.Type == typeof(IIxResolver))
                        {
                            (instanceLock.Target as IxResolver)?.ClearParentResolveContext();
                        }

                        return(resultItem);
                    }
                }

                return(await ResolveItem());
            }
        }
Ejemplo n.º 7
0
 public override ValueTask <IIxInstanceLock> GetInstance(
     IIxInstance parentInstance,
     IxIdentifier identifier,
     IxHost.IxResolveContext context,
     [CanBeNull] IxResolveFrame frame)
 {
     throw new NotImplementedException();
 }
Ejemplo n.º 8
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));
 }
Ejemplo n.º 9
0
 /// <inheritdoc/>
 public override async ValueTask <IIxInstanceLock> GetInstance(
     IIxInstance parentInstance,
     IxIdentifier identifier,
     IxHost.IxResolveContext context,
     [CanBeNull] IxResolveFrame frame)
 {
     Critical.Assert(false, "Not supported.");
     return(null);
 }
Ejemplo n.º 10
0
        public IxInstanceNoLock(IIxInstance target)
        {
            if (target == null)
            {
                throw new ArgumentNullException(nameof(target));
            }

            Target = target;
        }
Ejemplo n.º 11
0
        /// <inheritdoc/>
        public override async ValueTask <IIxInstanceLock> GetInstance(
            IIxInstance parentInstance,
            IxIdentifier identifier,
            IxHost.IxResolveContext context,
            [CanBeNull] IxResolveFrame frame)
        {
            if (parentInstance == null)
            {
                throw new ArgumentNullException(nameof(parentInstance));
            }

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

            IIxInstanceLock     creatorLock = null;
            IxSingletonInstance instance;

            // Re-implement this with more advanced Half-Instantiation with loop detection.
            lock (Host.InstanceTreeSyncRoot)
            {
                instance = parentInstance.GetData(this) as IxSingletonInstance;
                if (instance == null)
                {
                    // TODO: Detect cycles.
                    Debug.Assert(InstanceFactory != null, "InstanceFactory != null");

                    instance = new IxSingletonInstance(this, parentInstance, context, frame, out creatorLock);

                    parentInstance.SetData(this, instance);
                }
            }

            try
            {
                await instance.ObjectCreationTask;
                return(creatorLock ?? new IxInstancePinLock(instance));
            }
            catch
            {
                if (creatorLock != null)
                {
                    lock (Host.InstanceTreeSyncRoot)
                    {
                        parentInstance.SetData(this, null);
                    }

                    creatorLock.Dispose();
                }

                throw;
            }
        }
Ejemplo n.º 12
0
        /// <summary>
        /// Initializes a new instance of the <see cref="IxInstancePinLock"/> class.
        /// </summary>
        /// <param name="target">IndirectX instance.</param>
        public IxInstancePinLock(IIxInstance target)
        {
            Critical.Assert(target != null, "Pin lock target should not be null.");

            Target = target;

            lock (target.ProviderNode.Host.InstanceTreeSyncRoot)
            {
                Target.AddLock(this);
            }
        }
Ejemplo n.º 13
0
        private async ValueTask <IIxInstanceLock> RegistrationScopeBinder(
            IIxInstance originInstance,
            IxResolvePath resolvePath,
            IxResolveContext context,
            [CanBeNull] IxResolveFrame frame,
            IxResolveBoundDelegate resolveBound)
        {
            IIxInstance curInstance = originInstance;

            Critical.Assert(resolvePath.Path.Any(), "Registration scope binder does not support empty path.");

            lock (InstanceTreeSyncRoot)
            {
                while (curInstance != null)
                {
                    if (curInstance.ProviderNode == resolvePath.Root)
                    {
                        break;
                    }

                    curInstance = curInstance.ParentInstance;
                }
            }

            if (curInstance == null)
            {
                throw new InvalidOperationException("Resolve algorithms problems");
            }

            Func <IIxInstance, int, ValueTask <IIxInstanceLock> > resolvePathElements = null;

            resolvePathElements = async(parentInstance, index) =>
            {
                if (index < resolvePath.Path.Count - 1)
                {
                    using (IIxInstanceLock instanceLock = await Resolve(
                               parentInstance,
                               resolvePath.Path[index].Identifier,
                               context,
                               frame))
                    {
                        return(await resolvePathElements(instanceLock.Target, index + 1));
                    }
                }

                return(await resolveBound(parentInstance, resolvePath.Path.Last(), context));
            };

            IIxInstanceLock resultInstanceLock = await resolvePathElements(curInstance, 0);

            return(resultInstanceLock);
        }
Ejemplo n.º 14
0
            public IxResolveContext(
                IIxInstance originInstance,
                [CanBeNull] IxResolveContext parentContext,
                IReadOnlyDictionary <IxIdentifier, object> arguments)
            {
                Critical.CheckedAssert(originInstance != null, "Origin instance should be null.");
                Critical.CheckedAssert(arguments != null, "Arguments dictionary should not be null.");

                Arguments       = arguments;
                _originInstance = originInstance;
                ParentContext   = parentContext;
                _rootContext    = parentContext?._rootContext ?? this;

                Critical.CheckedAssert(_rootContext != null, "Root context should not be null.");
            }
Ejemplo n.º 15
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;
        }
Ejemplo n.º 16
0
        public IxInstanceChildLock(IIxInstance parent, IIxInstance child)
        {
            if (parent == null)
            {
                throw new ArgumentNullException(nameof(parent));
            }

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

            Target = parent;
            Owner  = child;

            lock (Target.ProviderNode.Host.InstanceTreeSyncRoot)
            {
                Target.AddLock(this);
                Owner.AddOwnedLock(this);
            }
        }
Ejemplo n.º 17
0
        /// <summary>
        /// Initializes a new instance of the <see cref="IxReferenceLock"/> class.
        /// </summary>
        /// <param name="target">The instance to lock.</param>
        /// <param name="owner">The owner of this lock.</param>
        public IxReferenceLock(IIxInstance target, IIxInstance owner)
        {
            if (target == null)
            {
                throw new ArgumentNullException(nameof(target));
            }

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

            Critical.Assert(!ReferenceEquals(target, owner), "Cannot create reference from self to self.");

            Target = target;
            Owner  = owner;

            lock (Target.ProviderNode.Host.InstanceTreeSyncRoot)
            {
                Target.AddLock(this);
                Owner.AddOwnedLock(this);
            }
        }
Ejemplo n.º 18
0
        private ResolveDelegate SelfToChildrenResolver(ResolveDelegate next)
        {
            return(async(originInstance, identifier, context, frame) =>
            {
                if (identifier.Name == null)
                {
                    IxResolvePath resolvePath;
                    if (originInstance.ProviderNode.VisibleNodes.TryGetValue(identifier, out resolvePath))
                    {
                        if (!resolvePath.Path.Any())
                        {
                            lock (InstanceTreeSyncRoot)
                            {
                                IIxInstance curInstance = originInstance;
                                while (curInstance != null)
                                {
                                    if (curInstance.ProviderNode == resolvePath.Root)
                                    {
                                        break;
                                    }

                                    curInstance = curInstance.ParentInstance;
                                }

                                Critical.Assert(
                                    curInstance != null,
                                    "Instance of an appropriate provider should be found.");

                                return new IxInstancePinLock(curInstance);
                            }
                        }
                    }
                }

                return await next(originInstance, identifier, context, frame);
            });
        }
Ejemplo n.º 19
0
 public abstract ValueTask <IIxInstanceLock> GetInstance(
     IIxInstance parentInstance,
     IxIdentifier identifier,
     IxHost.IxResolveContext context,
     [CanBeNull] IxResolveFrame frame);