Closed leonardolb closed 5 months ago
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
And don't forget to post a full stack trace
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
base.CreateBO
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;
}
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);
var dados = await client.Consultar(command.CNPJ).ConfigureAwait(false);
var results = await **ThirdPartyCommandMediator**.Handle(command).ConfigureAwait(false);
Yes! Exception is thrown at this line when resoling IPersonDataConfigBO
var documentosPessoa = base.CreateBO
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.
Sorry my misunderstanding!
I've debuged my code, scope is gone after
var response = await this._client.ExecuteAsync<CNPJ>(request).ConfigureAwait(false);
Unfortunately I can't debug further into ExecuteAsync as its is a method from RestSharp.RestClient class.
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.
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!
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.
Maybe i need to remove other ConfigureAwait I have so, maybe they are causing some trouble too i guess
Hi! i'm facing this error and I really can't go through it.
My code:
it start at this action:
goes to this block
and exception is thrown at the highlighted part of code.
Can anyone help me?
this is my lifestyle
It's an ASP.NET MVC5 app that runs some background tasks, WebAPI controllers and SignalR.
thanks!!