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)); }
#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); } }
/// <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()); } }
public override ValueTask <IIxInstanceLock> GetInstance( IIxInstance parentInstance, IxIdentifier identifier, IxHost.IxResolveContext context, [CanBeNull] IxResolveFrame frame) { throw new NotImplementedException(); }
/// <inheritdoc/> public override async ValueTask <IIxInstanceLock> GetInstance( IIxInstance parentInstance, IxIdentifier identifier, IxHost.IxResolveContext context, [CanBeNull] IxResolveFrame frame) { Critical.Assert(false, "Not supported."); return(null); }
/// <summary> /// Initializes a new instance of the <see cref="IxResolveTargetNotFound"/> class with a specified error message and inner /// exception. /// </summary> /// <param name="message">The message that describes the error. </param> /// <param name="identifier">Resolve target identifier.</param> /// <param name="innerException">Inner error.</param> public IxResolveTargetNotFound(string message, IxIdentifier identifier, Exception innerException) : base(message, innerException) { if (identifier == default(IxIdentifier)) { throw new ArgumentException("Identifier should not be empty.", nameof(identifier)); } Identifier = identifier; }
/// <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; } }
public async ValueTask <IIxInstanceLock> Resolve( IxIdentifier identifier, IReadOnlyDictionary <IxIdentifier, object> arguments = null) { var context = new IxResolveContext( OwnerInstance, ParentContext, arguments ?? new Dictionary <IxIdentifier, object>()); using (new IxInstancePinLock(OwnerInstance)) { return(await Host.Resolve(OwnerInstance, identifier, context, ParentFrame)); } }
/// <summary> /// Tries to get argument value for the provided identifier. /// </summary> /// <param name="identifier">Argument identifier.</param> /// <param name="context">The resolve context.</param> /// <returns>Argument instance lock or null, if no argument found for the provided identifier.</returns> public IIxInstanceLock TryGetInstance(IxIdentifier identifier, IxHost.IxResolveContext context) { IxHost.IxResolveContext curContext = context; while (curContext != null) { if (context.Arguments.TryGetValue(identifier, out var result)) { return(new IxInstancePinLock(new IxArgumentInstance(this, result))); } curContext = context.ParentContext; } // ReSharper disable once AssignNullToNotNullAttribute return(null); }
public abstract ValueTask <IIxInstanceLock> GetInstance( IIxInstance parentInstance, IxIdentifier identifier, IxHost.IxResolveContext context, [CanBeNull] IxResolveFrame frame);