Giter VIP home page Giter VIP logo

Comments (12)

dotnetjunkie avatar dotnetjunkie commented on June 12, 2024

Hi @leonardolb,

I've got trouble reading the images on my mobile phone. Would you mind replacing them with actual text, as was requested in the bug report template you used while filling in your question?

Thanks in advance

from simpleinjector.

dotnetjunkie avatar dotnetjunkie commented on June 12, 2024

And don't forget to post a full stack trace

from simpleinjector.

leonardolb avatar leonardolb commented on June 12, 2024

Sorry about that!!

Im facing this exception:

PersonDataConfigBO is registered using the 'Hybrid Async Scoped / Web Request' lifestyle, but the instance is requested outside the context of an active (Hybrid Async Scoped / Web Request) scope. Please see https://simpleinjector.org/scoped for more information about how apply lifestyles and manage scopes.

My stacktrace is:

SimpleInjector.ActivationException: PersonDataConfigBO is registered using the 'Hybrid Async Scoped / Web Request' lifestyle, but the instance is requested outside the context of an active (Hybrid Async Scoped / Web Request) scope. Please see https://simpleinjector.org/scoped for more information about how apply lifestyles and manage scopes.
at SimpleInjector.Scope.GetScopelessInstance(ScopedRegistration registration)
at SimpleInjector.Scope.GetInstance[TImplementation](ScopedRegistration registration, Scope scope)
at SimpleInjector.Advanced.Internal.LazyScopedRegistration1.GetInstance(Scope scope)
at lambda_method(Closure )
at SimpleInjector.InstanceProducer.GetInstance()
at SimpleInjector.Container.GetInstance[TService]()
at AdSolutions.AdData.Context.Pessoa.PessoaContext.<ConsultarCNPJ>d__3.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter1.GetResult()
at AdSolutions.Site.AdData.Controllers.PersonController.<Detail>d__3.MoveNext() in C:\Users\leonardo\Desktop\svn\AdTraffic\master\AdSolutions.Site.Host\Areas\AdData\Controllers\PersonController.cs:line 100
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Web.Mvc.Async.TaskAsyncActionDescriptor.EndExecute(IAsyncResult asyncResult)
at System.Web.Mvc.Async.AsyncControllerActionInvoker.<>c__DisplayClass8_0.<BeginInvokeAsynchronousActionMethod>b__1(IAsyncResult asyncResult)
at System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeActionMethod(IAsyncResult asyncResult)
at System.Web.Mvc.Async.AsyncControllerActionInvoker.AsyncInvocationWithFilters.<>c__DisplayClass11_0.<InvokeActionMethodFilterAsynchronouslyRecursive>b__0()
at System.Web.Mvc.Async.AsyncControllerActionInvoker.AsyncInvocationWithFilters.<>c__DisplayClass11_2.<InvokeActionMethodFilterAsynchronouslyRecursive>b__2()
at System.Web.Mvc.Async.AsyncControllerActionInvoker.AsyncInvocationWithFilters.<>c__DisplayClass11_2.<InvokeActionMethodFilterAsynchronouslyRecursive>b__2()
at System.Web.Mvc.Async.AsyncControllerActionInvoker.AsyncInvocationWithFilters.<>c__DisplayClass11_2.<InvokeActionMethodFilterAsynchronouslyRecursive>b__2()
at System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeActionMethodWithFilters(IAsyncResult asyncResult)
at System.Web.Mvc.Async.AsyncControllerActionInvoker.<>c__DisplayClass3_6.<BeginInvokeAction>b__4()
at System.Web.Mvc.Async.AsyncControllerActionInvoker.<>c__DisplayClass3_1.<BeginInvokeAction>b__1(IAsyncResult asyncResult)`

Everything start at my PersonController "Detail" Action. It async calls "ConsultarCNPJ" in my context class

public async Task<JsonResult> Detail(PessoaModel model, PessoaDadoPessoaConfigModel documento)
{
    if (model == null)
        model = new PessoaModel();

    var service = base.CreateContext<IPessoaContext>();

    if (documento != null)
    {
        var consultarCnpj = false;

        if (consultarCnpj.False())
            model = service.ObterNovo(documento);
        else
            **_model = await service.ConsultarCNPJ(documento);_**
    }
    else if (model.State.In(ModelStateType.Normal))
        model = service.ObterDetalhes(model);

    return AjaxViewResult(new PessoaViewModel(model));
}

"ConsultarCNPJ" is a simple method that triggers a mediator (ThirdPartyCommandMediator) and awaits all available commands complete (just one expected for this ConsultarCNPJThirdPartyCommand).

When finished, base.CreateBO().List is called to continue some procedures.

base.CreateBO().List is not async and it goes to directly to database (oracle).

CreateBO method is just a wrapper to simpleinjector Container.Resolve.

public async Task<PessoaModel> ConsultarCNPJ(PessoaDadoPessoaConfigModel documento)
{
    var command = new ConsultarCNPJThirdPartyCommand
    {
        CNPJ = documento.dsValor.RemoveSpecialCharacters().RemoveDiacritics()
    };

    var results = await **ThirdPartyCommandMediator**.Handle(command).ConfigureAwait(false);

    var queryData = results[0];

    if (queryData.Success)
    {
        var pessoa = queryData.Command.ReturnValue.Pessoa;

        var documentosPessoa = **base.CreateBO<IPersonDataConfigBO>().List**(
            new PaisModel { sqPais = PaisModel.Brasil },
            TipoPessoa.Juridica,
            Situacao.Ativo).Select(sel => new PessoaDadoPessoaConfigModel
            {
                DadoPessoaConfig = sel,
                State = ModelStateType.New
            }).ToList();
}

I'm using "Lifestyle = Lifestyle.CreateHybrid(new SimpleInjector.Lifestyles.AsyncScopedLifestyle(), new WebRequestLifestyle())" as my lifestyle.

Finally, this is the Handler triggered when ThirdPartyCommandMediator.Handle() is invoked

public override async Task<ThirdPartyCommandHandlerContext<ConsultarCNPJThirdPartyCommand>>
    Handle(ThirdPartyCommandHandlerContext<ConsultarCNPJThirdPartyCommand> commandContext)
{

    var targetApp = new SERPROPartyApp(commandContext.Context);
    var command = commandContext.Command;

    if (targetApp.BaseUrl.IsNullOrWhiteSpace())
        return commandContext;
    else
    {
        var client = new SERPRORestClient(targetApp.Username, targetApp.Password, targetApp.BaseUrl);

        var dados = await client.Consultar(command.CNPJ).ConfigureAwait(false);
    }
}


public async Task<CNPJ> Consultar(string cnpj)
{
    var request = new RestRequest("/consulta-cnpj-df/v2/basica/" + cnpj, Method.Get);

    var response = await this._client.ExecuteAsync<CNPJ>(request).ConfigureAwait(false);

    return response?.Data;
}

from simpleinjector.

dotnetjunkie avatar dotnetjunkie commented on June 12, 2024

Can you debug through your application and determine exactly after which line of code the scope is gone? e.g. is that after:

  • var response = await this._client.ExecuteAsync<CNPJ>(request).ConfigureAwait(false);
  • or after var dados = await client.Consultar(command.CNPJ).ConfigureAwait(false);
  • or after var results = await **ThirdPartyCommandMediator**.Handle(command).ConfigureAwait(false);
  • or later?

from simpleinjector.

leonardolb avatar leonardolb commented on June 12, 2024

Yes!
Exception is thrown at this line when resoling IPersonDataConfigBO

var documentosPessoa = base.CreateBO().List in ConsultarCNPJ method.

from simpleinjector.

dotnetjunkie avatar dotnetjunkie commented on June 12, 2024

Sorry, that's not what I meant. It's clear to me where the exception is thrown, but there is a point in the application that Simple Injector's Scope is gone. This is what eventually leads to the exception. What I want to know is: what is the first ocurrance in your code where that Scope is gone. This will likely be long before the exception happens.

In order to test this, you might need to make some temporary adjustments to your code; the easiest way to test is by calling into the container to resolve a scoped dependency, for instance just after the lines of code I mentioned above.

from simpleinjector.

leonardolb avatar leonardolb commented on June 12, 2024

Sorry my misunderstanding!

I've debuged my code, scope is gone after

var response = await this._client.ExecuteAsync<CNPJ>(request).ConfigureAwait(false);

from simpleinjector.

leonardolb avatar leonardolb commented on June 12, 2024

Unfortunately I can't debug further into ExecuteAsync as its is a method from RestSharp.RestClient class.

from simpleinjector.

dotnetjunkie avatar dotnetjunkie commented on June 12, 2024

That likely means that there is something happening within RestSharp.RestClient that causes the asynchronous context not to flow. The most likely case is that it is using an async foreach like construct over IAsyncEnumerable. This can cause the asynchronous context to be cleared and Microsoft hasn't provided a fix for this. Although you could try posting a bug report with RestSharp.RestClient, chances are slim that the makers will act on this.

What you can do instead is make sure that all your dependencies for that scope are resolved before this point. This means stepping away from lazy loading your dependencies, as you are doing right now.

from simpleinjector.

leonardolb avatar leonardolb commented on June 12, 2024

Thanks!
I've removed .ConfigureAwait(false) from it just to test and scope stopped being lost. However, I don't feel I should do it as it may cause deadlock at some background tasks that consumes this same method.

I'll step away from lazyloading so!

thanks!

from simpleinjector.

dotnetjunkie avatar dotnetjunkie commented on June 12, 2024

I've removed .ConfigureAwait(false)

I didn't expect this.

However, I don't feel I should do it as it may cause deadlock at some background tasks that consumes this same method.

You don't have to worry about that. This only holds when building client applications such as WPF and Win Forms. This doesn't hold for ASP.NET. AFAIK, It will never deadlock on this.

from simpleinjector.

leonardolb avatar leonardolb commented on June 12, 2024

Maybe i need to remove other ConfigureAwait I have so, maybe they are causing some trouble too i guess

from simpleinjector.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.