示例#1
0
 public TDependency ResolveDependency <TDependency>(IDependencyResolutionContext context)
     where TDependency : class
 {
     //
     ResolveDependency(ctx: context, dependency: out TDependency result);
     return(result);
 }
示例#2
0
            public override bool Invoke(DependencyScope scope, IDependencyResolutionContext ctx, out object dependency)
            {
                scope.EnsureNotNull(nameof(scope));
                //
                var result = scope.ResolveDependency(ctx, out TDependency locDependency);

                dependency = locDependency;
                return(result);
            }
示例#3
0
        /// <summary>
        /// Resolve an ILog instance for a DependencyResolutionContext
        /// </summary>
        protected override ILog ResolveInternal(IDependencyResolutionContext context)
        {
            // Just in case we don't have enough information just return a generic logger.
            if (context.Request == null || context.Request.RequestedType == null)
            {
                return(Get <ILog>());
            }

            // Resolve a log instance for the Type requesting a log dependency.
            return(Get(context.Request.RequestedType));
        }
 // TODO: Put strings into the resources.
 //
 public virtual DependencyResult ExecuteResolution(IDependencyResolutionContext resolutionCtx)
 {
     resolutionCtx.EnsureNotNull(nameof(resolutionCtx));
     //
     if (resolutionCtx.Specs.IsNewInstanceRequired)
     {
         return(DependencyResult.None);
     }
     else
     {
         var scope    = _hasServiceScope ? ServiceScope : null;
         var sp       = scope is null ? ServiceProvider : scope.ServiceProvider;
         var instance = rethrowSpException(locOp: locSp => locSp.GetService(serviceType: resolutionCtx.Specs.DependencyType), locSp: sp, locScope: scope);
         if (instance is null)
         {
             return(DependencyResult.None);
         }
         else
         {
             return(new DependencyResult(instance: instance, isNewInstance: false));
         }
     }
     //
     object rethrowSpException(Func <IServiceProvider, object> locOp, IServiceProvider locSp, IServiceScope locScope)
     {
         try {
             return(locOp(arg: locSp));
         }
         catch (Exception exception) {
             throw
                 new EonException(
                     message: $"The service provider has thrown an exception while handling the dependency resolution request.{Environment.NewLine}Service provider:{locSp.FmtStr().GNLI2()}{(locScope is null ? string.Empty : $"{Environment.NewLine}Service scope:{locScope.FmtStr().GNLI2()}")}{Environment.NewLine}Component:{this.FmtStr().GNLI2()}",
                     innerException: exception)
                 .SetErrorCode(code: DependencyErrorCodes.Fault);
         }
     }
 protected abstract DependencyResult ResolveDependency(IDependencyResolutionContext context);
示例#6
0
 protected override Task <DependencyResult <TDependencyInstance> > ResolveNewDependencyInstanceAsync(IDependencyResolutionContext context)
 {
     try {
         var specs =
             context
             .EnsureNotNull(nameof(context))
             .Value
             .Specs;
         //
         var factoryArgs = ReadDA(ref _factoryArgs);
         if (factoryArgs == null)
         {
             if ((factoryArgs = specs.NewInstanceFactoryArgs as IArgsTuple <TArg1, TArg2, TArg3, TArg4>) == null || factoryArgs.ArgsCount != __ArgsCount)
             {
                 return(TaskUtilities.FromResult(DependencyResult <TDependencyInstance> .None));
             }
         }
         else if (specs.NewInstanceFactoryArgs != null)
         {
             return(TaskUtilities.FromResult(DependencyResult <TDependencyInstance> .None));
         }
         //
         return
             (TaskUtilities
              .FromResult(
                  result:
                  new DependencyResult <TDependencyInstance>(
                      instance:
                      ReadDA(ref _getDependencyCtor)
                          ()
                          (factoryArgs.Arg1, factoryArgs.Arg2, factoryArgs.Arg3, factoryArgs.Arg4),
                      isNewInstance: true)));
     }
     catch (Exception firstException) {
         return(Task.FromException <DependencyResult <TDependencyInstance> >(firstException));
     }
 }
示例#7
0
        protected override async Task <DependencyResult <TDependencyInstance> > ResolveDependencyAsync(IDependencyResolutionContext ctx)
        {
            var specs = ctx.EnsureNotNull(nameof(ctx)).Value.Specs;

            //
            if (specs.DependencyType.IsAssignableFrom(DependencyInstanceType))
            {
                var newInstanceResult = default(DependencyResult <TDependencyInstance>);
                if (specs.IsNewInstanceRequired || !CanShareDependency)
                {
                    try {
                        newInstanceResult = await ResolveNewDependencyInstanceAsync(ctx : ctx).ConfigureAwait(false);

                        if (newInstanceResult.Instance is null)
                        {
                            return(newInstanceResult);
                        }
                        else if (!newInstanceResult.IsNewInstance)
                        {
                            throw
                                new EonException(
                                    message: $"Результат вызова метода '{nameof(ResolveNewDependencyInstanceAsync)}' не соответствует ожидаемому. В частности, свойство результата '{nameof(newInstanceResult)}.{nameof(newInstanceResult.IsNewInstance)}' не соответствует ожидаемому значение '{bool.TrueString}'.");
                        }
                        else if (specs.PreventNewInstanceInitialization)
                        {
                            return(newInstanceResult);
                        }
                        else
                        {
                            await P_InitializeNewDependencyInstanceAsync(instance : newInstanceResult.Instance).ConfigureAwait(false);

                            return(newInstanceResult);
                        }
                    }
                    catch (Exception exception) {
                        if (newInstanceResult.IsNewInstance)
                        {
                            (newInstanceResult.Instance as IDisposable)?.Dispose(exception);
                        }
                        throw;
                    }
                }
                else
                {
                    // В спецификации запроса отсутствует требование разрешения зависимости именно в новый экземпляр (см. specs.IsNewInstanceRequired) + обработчик может "шарить" экземпляр (см. CanShareDependency).
                    //
                    var sharedInstanceStore = ReadDA(ref _sharedInstanceStore);
                    if (sharedInstanceStore is null)
                    {
                        var lck         = ReadDA(ref _sharedInstanceInitializationLock);
                        var lckAcquired = false;
                        try {
                            lckAcquired = await lck.WaitAsync(millisecondsTimeout : TaskUtilities.DefaultAsyncTimeoutMilliseconds).ConfigureAwait(false);

                            if (!lckAcquired)
                            {
                                throw new LockAcquisitionFailException(reason: LockAcquisitionFailReason.TimeoutElapsed);
                            }
                            //
                            sharedInstanceStore = ReadDA(ref _sharedInstanceStore);
                            if (sharedInstanceStore is null)
                            {
                                try {
                                    newInstanceResult = await ResolveNewDependencyInstanceAsync(ctx : ctx).ConfigureAwait(false);

                                    if (newInstanceResult.Instance is null)
                                    {
                                        WriteDA(location: ref _sharedInstanceStore, value: sharedInstanceStore = default(TDependencyInstance).ToValueHolder(ownsValue: false));
                                    }
                                    else if (!newInstanceResult.IsNewInstance)
                                    {
                                        throw
                                            new EonException(
                                                message: $"Результат вызова метода '{nameof(ResolveNewDependencyInstanceAsync)}' не соответствует ожидаемому. В частности, свойство результата '{nameof(newInstanceResult)}.{nameof(newInstanceResult.IsNewInstance)}' не соответствует ожидаемому значение '{bool.TrueString}'.");
                                    }
                                    else if (specs.PreventNewInstanceInitialization)
                                    {
                                        WriteDA(
                                            location: ref _sharedInstanceStore,
                                            value: sharedInstanceStore = newInstanceResult.Instance.ToValueHolder(ownsValue: true));
                                    }
                                    else
                                    {
                                        try {
                                            await P_InitializeNewDependencyInstanceAsync(instance : newInstanceResult.Instance).ConfigureAwait(false);

                                            sharedInstanceStore = newInstanceResult.Instance.ToValueHolder(ownsValue: true);
                                        }
                                        catch (Exception exception) {
                                            sharedInstanceStore = new Vh <TDependencyInstance>(exception: exception);
                                        }
                                        WriteDA(location: ref _sharedInstanceStore, value: sharedInstanceStore);
                                    }
                                }
                                catch (Exception exception) {
                                    if (newInstanceResult.IsNewInstance && !ReferenceEquals(itrlck.Get(ref _sharedInstanceStore)?.ValueDisposeTolerant, newInstanceResult.Instance))
                                    {
                                        (newInstanceResult.Instance as IDisposable)?.Dispose(exception);
                                    }
                                    throw;
                                }
                            }
                        }
                        finally {
                            if (lckAcquired)
                            {
                                try { lck.Release(); }
                                catch (ObjectDisposedException) { }
                            }
                        }
                    }
                    if (sharedInstanceStore.Value is null)
                    {
                        return(DependencyResult <TDependencyInstance> .None);
                    }
                    else
                    {
                        return(new DependencyResult <TDependencyInstance>(instance: sharedInstanceStore.Value, isNewInstance: false));
                    }
                }
            }
            else
            {
                return(DependencyResult <TDependencyInstance> .None);
            }
        }
示例#8
0
 protected abstract Task <DependencyResult <TDependencyInstance> > ResolveNewDependencyInstanceAsync(IDependencyResolutionContext ctx);
 protected override Task <DependencyResult <TDependencyInstance> > ResolveNewDependencyInstanceAsync(IDependencyResolutionContext context)
 {
     try {
         var specs = context.EnsureNotNull(nameof(context)).Value.Specs;
         //
         var factoryArgs = ReadDA(ref _factoryArgs);
         if (factoryArgs is null)
         {
             // Поскольку в данном обработчике явно не заданы параметры конструктора нового экземпляра, используются те, что указаны в спецификации, если они подходят для использования (см. код ниже).
             //
             if ((factoryArgs = specs.NewInstanceFactoryArgs as IArgsTuple <TArg1>) == null || factoryArgs.ArgsCount != __ArgsCount)
             {
                 return(TaskUtilities.FromResult(DependencyResult <TDependencyInstance> .None));
             }
         }
         else if (!(specs.NewInstanceFactoryArgs is null))
         {
             // Поскольку спецификацией явно определены параметры конструктора нового экземпляра, а также явно заданны в данном обработчике (factoryArgs != null), то получается конфликт.
             //
             return(TaskUtilities.FromResult(DependencyResult <TDependencyInstance> .None));
         }
         return
             (TaskUtilities
              .FromResult(
                  result:
                  new DependencyResult <TDependencyInstance>(
                      instance: ReadDA(ref _getDependencyCtor)()(factoryArgs.Arg1),
                      isNewInstance: true)));
     }
     catch (Exception exception) {
         return(Task.FromException <DependencyResult <TDependencyInstance> >(exception));
     }
 }
示例#10
0
 DependencyResult IDependencyHandler.ExecuteResolution(IDependencyResolutionContext resolutionCtx)
 => DependencyResult.None;
示例#11
0
 /// <summary>
 /// Resolve an Instance of a Dependency
 /// </summary>
 /// <param name="context">Context information about the request for a dependency.</param>
 /// <returns></returns>
 public TInstance Resolve(IDependencyResolutionContext context)
 {
     return(ResolveInternal(context));
 }
示例#12
0
 public abstract bool Invoke(DependencyScope scope, IDependencyResolutionContext ctx, out object dependency);
示例#13
0
        // TODO: Put strings into the resources.
        //
        public virtual bool ResolveDependency <TDependency>(IDependencyResolutionContext ctx, out TDependency dependency)
            where TDependency : class
        {
            //
            ctx.EnsureNotNull(nameof(ctx));
            if (!ReferenceEquals(ctx.Scope, this))
            {
                throw
                    new ArgumentOutOfRangeException(
                        paramName: nameof(ctx),
                        message: $"Указанный контекст не принадлежит данной области функциональной зависимости.{Environment.NewLine}\tКонтекст:{ctx.FmtStr().GNLI2()}{Environment.NewLine}\tОбласть:{this.FmtStr().GNLI2()}");
            }
            else if (!typeof(TDependency).IsAssignableFrom(ctx.Specs.DependencyType))
            {
                throw
                    new ArgumentOutOfRangeException(
                        paramName: nameof(ctx),
                        message: $"Тип функциональной зависимости '{ctx.Specs.DependencyType}', определенный параметрами указанного контекста '{ctx}', не совместим с типом функциональной зависимости '{typeof(TDependency)}', указанным для данного вызова разрешения функциональной зависимости.");
            }
            //
            if (ctx.Specs.IsNewInstanceRequired && _prohibitNewInstanceRequest)
            {
                throw new EonException(message: $"Для данной области функциональной зависимости запрещены запросы на разрешение зависимости в новый экземпляр.{Environment.NewLine}\tОбласть:{this.FmtStr().GNLI2()}");
            }
#if DO_NOT_USE_EON_LOGGING_API
            if (ctx.IsAdvancedLoggingEnabled)
            {
                throw new NotSupportedException(message: $"В тек. версии расширенное логирование разрешения функциональной зависимости (см. {nameof(ctx)}.{nameof(ctx.IsAdvancedLoggingEnabled)}) не поддерживается.").SetErrorCode(code: GeneralErrorCodes.Operation.NotSupported);
            }
#else
            var isContextAdvancedLoggingEnabled = ctx.IsAdvancedLoggingEnabled;
#endif
            //
            var ensureResolution      = ctx.Specs.EnsureResolution;
            var isNewInstanceRequired = ctx.Specs.IsNewInstanceRequired;
            var selectCriterion       = ctx.Specs.SelectCriterion;
            var errorMessagePrologue  = $"Было затребовано разрешение функциональной зависимости.{Environment.NewLine}Функциональная зависимость:{Environment.NewLine}{typeof(TDependency).FmtStr().G().IndentLines()}{Environment.NewLine}Параметры разрешения:{Environment.NewLine}{ctx.Specs.ToString().IndentLines()}.";
            //
            List <IDependencyHandler2> currentScopeHandlersTraversal;
            IDependencyHandler2        currentHandler;
            object      resultDependencyInstanceAsObject;
            IDisposable resultInstanceAsDisposable;
            var         resultInstance = default(TDependency);
            var         handlerResult  = DependencyResult.None;
            //
            var newDependencyInstancesDisposeRegistry = ctx.Specs.DisposeRegistry ?? ReadDA(ref _newDependencyInstancesDisposeRegistry);
            //
            var runningResolutionsSpinLock   = ReadDA(ref _runningResolutionsSpinLock);
            var runningResolutionsUniqueness = ReadDA(ref _runningResolutionsUniqueness);
            var runningResolutionsSequence   = ReadDA(ref _runningResolutionsSequence);
            //
            var involvedScopes = new HashSet <IDependencyScope>(comparer: ReferenceEqualityComparer <IDependencyScope> .Instance);
            try {
                // Регистрация выполнения запроса ф. зависимости.
                //
                runningResolutionsSpinLock
                .Invoke(
                    () => {
                    EnsureNotDisposeState();
                    //
                    if (runningResolutionsSequence.Count >= MaxCountOfRunningResolutions)
                    {
                        throw
                        new EonException(
                            message: $"{errorMessagePrologue}{Environment.NewLine}Для области функциональной зависимости достигнут предел '{MaxCountOfRunningResolutions}' максимального количества одновременно выполняющихся вызовов разрешения функциональной зависимости.{Environment.NewLine}\tОбласть функциональной зависимости:{this.FmtStr().GNLI2()}")
                        .SetErrorCode(DependencyErrorCodes.Fault);
                    }
                    else if (runningResolutionsUniqueness.Add(item: ctx))
                    {
                        runningResolutionsSequence.Add(item: ctx);
                    }
                    else
                    {
                        throw
                        new EonException(
                            message: $"{errorMessagePrologue}{Environment.NewLine}Указанный контекст уже используется другим вызовом разрешения функциональной зависимости в данной области функциональной зависимости.{Environment.NewLine}\tКонтекст:{ctx.FmtStr().GNLI2()}{Environment.NewLine}\tОбласть функциональной зависимости:{this.FmtStr().GNLI2()}")
                        .SetErrorCode(DependencyErrorCodes.Fault);
                    }
                });
                //
                var thisScope     = (IDependencyScope)this;
                var previousScope = default(IDependencyScope);
                foreach (var currentScope in thisScope.TreeNode().SelfAndAncestors(parentSelector: locItem => locItem.GetOuterScope()))
                {
                    if (!involvedScopes.Add(currentScope))
                    {
                        throw
                            new EonException(
                                message: $"{errorMessagePrologue}{Environment.NewLine}Указанная область функциональной зависимости в составе окружающих (внешних) областей для данной области повторяется, что недопустимо.{Environment.NewLine}\tДанная область:{this.FmtStr().GNLI2()}{Environment.NewLine}\tУказанная область:{this.FmtStr().GNLI2()}{Environment.NewLine}\tОбласть, предшествующая указанной:{previousScope.FmtStr().GNLI2()}")
                            .SetErrorCode(DependencyErrorCodes.Fault);
                    }
                    // Составить упорядоченный список обхода обработчиков запроса ф. зависимости.
                    //
                    currentScopeHandlersTraversal = new List <IDependencyHandler2>(collection: currentScope.GetResolutionModel());
                    if (involvedScopes.Count == 1)
                    {
                        // Сначала должны быть использованы обработчики запроса ф. зависимости первичной модели (если она задана), поэтому они добавляются в начало списка обхода.
                        //
                        var primaryModel = ctx.Specs.PrimaryResolutionModel.EmptyIfNull();
                        if (currentScopeHandlersTraversal.Count == 0)
                        {
                            currentScopeHandlersTraversal.AddRange(collection: primaryModel);
                        }
                        else
                        {
                            currentScopeHandlersTraversal.InsertRange(index: 0, collection: primaryModel);
                        }
                        //
                        previousScope = currentScope;
                    }
                    // Обход списка обработчиков запроса ф. зависимости.
                    //
                    var currentHandlerIndex    = 0;
                    var handlerRedirectCounter = 0;
                    for (; resultInstance is null && currentHandlerIndex < currentScopeHandlersTraversal.Count;)
                    {
                        currentHandler = currentScopeHandlersTraversal[currentHandlerIndex];
                        //
                        if (currentHandler != null && ctx.TryInvolveHandler(handler: currentHandler))
                        {
                            resultInstanceAsDisposable = (resultDependencyInstanceAsObject = (handlerResult = currentHandler.ExecuteResolution(resolutionCtx: ctx)).Instance) as IDisposable;
                            if (resultDependencyInstanceAsObject is null)
                            {
                                if (!(handlerResult.RedirectHandler is null))
                                {
                                    if (handlerRedirectCounter++ < DefaultOfMaxCountOfResolutionRedirect)
                                    {
                                        var redirectHandlerIndex = currentHandlerIndex + 1;
                                        if (redirectHandlerIndex < currentScopeHandlersTraversal.Count)
                                        {
                                            currentScopeHandlersTraversal.Insert(index: redirectHandlerIndex, item: handlerResult.RedirectHandler);
                                        }
                                        else
                                        {
                                            currentScopeHandlersTraversal.Add(item: handlerResult.RedirectHandler);
                                        }
                                    }
                                    else
                                    {
                                        throw
                                            new EonException(
                                                message: $"Dependency resolution was broken due to the count of dependency handlers redirects reached the limit — {DefaultOfMaxCountOfResolutionRedirect:d} (see {nameof(DependencyScope)}.{nameof(DefaultOfMaxCountOfResolutionRedirect)}).{Environment.NewLine}Redirect from handler:{currentHandler.FmtStr().GNLI2()}{Environment.NewLine}Redirect to handler:{handlerResult.RedirectHandler.FmtStr().GNLI2()}{Environment.NewLine}Scope:{currentScope.FmtStr().GNLI2()}")
                                            .SetErrorCode(code: DependencyErrorCodes.Fault);
                                    }
                                }
                            }
                            else if ((resultInstance = resultDependencyInstanceAsObject as TDependency) is null)
                            {
                                throw
                                    new EonException(
                                        $"{errorMessagePrologue}{Environment.NewLine}Компонент, исполняющий разрешение функциональной зависимости, возвратил недопустимый результат. Тип '{resultDependencyInstanceAsObject.GetType()}' экземпляра, полученного от компонента, не совместим с требуемым типом '{typeof(TDependency)}'.{Environment.NewLine}\tКомпонент:{currentHandler.FmtStr().GNLI2()}")
                                    .SetErrorCode(DependencyErrorCodes.Fault);
                            }
                            else if (ctx.Specs.IsNewInstanceRequired && !handlerResult.IsNewInstance)
                            {
                                throw
                                    new EonException(
                                        $"{errorMessagePrologue}{Environment.NewLine}Компонент, исполняющий разрешение функциональной зависимости, возвратил недопустимый результат. От компонента было затребовано создание нового экземпляра, но компонент возвратил результат, указывающий, что экземпляр не является новым.{Environment.NewLine}\tКомпонент:{currentHandler.FmtStr().GNLI2()}")
                                    .SetErrorCode(DependencyErrorCodes.Fault);
                            }
                            else if (!ctx.IsMatchSelectCriterion(resultInstance))
                            {
                                if (handlerResult.IsNewInstance)
                                {
                                    resultInstanceAsDisposable?.Dispose();
                                }
                                resultInstanceAsDisposable       = null;
                                resultDependencyInstanceAsObject = null;
                                resultInstance = null;
                            }
                            else if (handlerResult.IsNewInstance && resultInstanceAsDisposable != null)
                            {
                                newDependencyInstancesDisposeRegistry.Register(resultInstanceAsDisposable);
                            }
                        }
                        //
#if !DO_NOT_USE_EON_LOGGING_API
                        if (isContextAdvancedLoggingEnabled && !(resultDependencyInstance is null))
                        {
                            string loggingInformationMessage;
                            using (var acquiredBuffer = StringBuilderUtilities.AcquireBuffer()) {
                                var sb = acquiredBuffer.StringBuilder;
                                sb.AppendLine($"Функциональная зависимость разрешена.");
                                sb.AppendLine($"\tПараметры разрешения:");
                                sb.AppendLine(ctx.Specs.ToString().IndentLines(indentSize: 2));
                                sb.AppendLine($"\tЭкземпляр зависимости:");
                                sb.Append(resultDependencyInstance.ToString().IndentLines(indentSize: 2));
                                loggingInformationMessage = sb.ToString();
                            }
                            context.IssueInformation($"Разрешение функциональной зависимости (ИД контекста '{contextSequentialId:d}').", loggingInformationMessage);
                        }
#endif
                        //
                        currentHandlerIndex++;
                    }
                    //
                    if (resultInstance != null)
                    {
                        break;
                    }
                }
            }
            catch (Exception exception) {
                if (handlerResult.IsNewInstance)
                {
                    DisposableUtilities.DisposeMany(exception, handlerResult.Instance as IDisposable);
                }
                throw;
            }
            finally {
                runningResolutionsSpinLock
                .Invoke(
                    () => {
                    if (!(Disposing || IsDisposed))
                    {
                        runningResolutionsSequence.RemoveAll(match: locItem => ReferenceEquals(objA: locItem, objB: ctx));
                        runningResolutionsUniqueness.Remove(item: ctx);
                    }
                });
            }
            //
            if (resultInstance is null)
            {
                if (ensureResolution)
                {
                    // Формирование текста сообщения ошибки.
                    //
                    // TODO: involvedExecutorsChainShowReportMaxCount сделать конфигурируемым.
                    //
                    var    involvedExecutorsChainShowReportMaxCount = FormatStringUtilities.DefaultMaxCountOfCollectionOutputItems;
                    string involvedExecutorsChainReport;
                    IDependencyHandler2[] involvedHandlerChain;
                    string involvedHandlerText(IDependencyHandler2 locHandler)
                    => $"Объект:{locHandler.FmtStr().GNLI()}";

                    using (var buffer = EonStringBuilderUtilities.AcquireBuffer()) {
                        var sb = buffer.StringBuilder;
                        involvedHandlerChain = ctx.GetInvolvedHandlerChain();
                        var involvedExecutorsChainLimit = Math.Min(involvedExecutorsChainShowReportMaxCount, involvedHandlerChain.Length);
                        for (var k = 0; k < involvedExecutorsChainLimit; k++)
                        {
                            if (k > 0)
                            {
                                sb.AppendLine();
                            }
                            sb.Append($"{(k + 1):d}) {involvedHandlerText(involvedHandlerChain[ k ])}");
                        }
                        if (involvedHandlerChain.Length > involvedExecutorsChainShowReportMaxCount)
                        {
                            if (involvedHandlerChain.Length - involvedExecutorsChainShowReportMaxCount < 3)
                            {
                                sb.Append($"{Environment.NewLine}{(involvedExecutorsChainShowReportMaxCount + 1):d}) {involvedHandlerText(involvedHandlerChain[ involvedExecutorsChainShowReportMaxCount ])}");
                            }
                            else
                            {
                                sb.Append($"{Environment.NewLine}…");
                            }
                            //
                            if (involvedHandlerChain.Length > (involvedExecutorsChainShowReportMaxCount + 1))
                            {
                                sb.Append($"{Environment.NewLine}{(involvedHandlerChain.Length):d}) {involvedHandlerText(involvedHandlerChain[ involvedHandlerChain.Length - 1 ])}");
                            }
                        }
                        involvedExecutorsChainReport = sb.ToString();
                    }
                    throw
                        new EonException(
                            $"{errorMessagePrologue}{Environment.NewLine}Указанная зависимость не была разрешена.{Environment.NewLine}Детали:{Environment.NewLine}\tОбласть функциональной зависимости:{Environment.NewLine}{this.FmtStr().GI2()}{Environment.NewLine}\tПоследовательность задействованных обработчиков (длина {involvedHandlerChain.Length:d}):{Environment.NewLine}{involvedExecutorsChainReport.IndentLines2()}")
                        .SetErrorCode(DependencyErrorCodes.Resolution_NotResolved);
                }
                else
                {
                    dependency = null;
                    return(false);
                }
            }
            else
            {
                dependency = resultInstance;
                return(true);
            }
        }
示例#14
0
 protected sealed override DependencyResult ResolveDependency(IDependencyResolutionContext context)
 => ResolveDependencyAsync(context: context).WaitResultWithTimeout();
 DependencyResult IDependencyHandler.ExecuteResolution(IDependencyResolutionContext context)
 => ResolveDependency(context: context);
 protected override Task <DependencyResult <TDependencyInstance> > ResolveNewDependencyInstanceAsync(IDependencyResolutionContext context)
 {
     try {
         var specs = context.EnsureNotNull(nameof(context)).Value.Specs;
         //
         if ((specs.NewInstanceFactoryArgs?.ArgsCount ?? 0) != __ArgsCount)
         {
             return(TaskUtilities.FromResult(DependencyResult <TDependencyInstance> .None));
         }
         else
         {
             return
                 (TaskUtilities
                  .FromResult(
                      result:
                      new DependencyResult <TDependencyInstance>(
                          instance: ReadDA(ref _getDependencyCtor, considerDisposeRequest: true)()(),
                          isNewInstance: true)));
         }
     }
     catch (Exception exception) {
         return(Task.FromException <DependencyResult <TDependencyInstance> >(exception));
     }
 }
示例#17
0
 /// <summary>
 /// Derived implementations must provide the internal mechanism to resolve an instance of the requested dependency.
 /// </summary>
 /// <param name="context">Context information about the request for a dependency.</param>
 protected abstract TInstance ResolveInternal(IDependencyResolutionContext context);