I want to change scope of service instance scope from Singleton to Transient(where it create instance every request) using service url but getting compile time error
Below is working code without service url
services.AddTransient(typeof(IUser), typeof(My.UserService));
Below is singleton scope with service url
services.AddSingleton(typeof(IUser), ServiceProxy.Create<IUser>(new Uri("fabric:/My.Microservices/MY.UserService")));
Now I want to add scope as Transient using service url like singleton, how?
Use the generic approach for registering your service, along with a factory delegate
services.AddTransient<IUser>(sp =>
ServiceProxy.Create<IUser>(new Uri("fabric:/My.Microservices/MY.UserService"))
);
In the above code, every time IUser is resolved the delegate will be invoked.
Related
I register a service as Singleton in the program.cs file like this.
builder.Services.AddSingleton<ITest, Test>();
and if I request an instance of it in program.cs
var testService = builder.Services.BuildServiceProvider()
.GetRequiredService<ITest>();
It creates a new object which is the first object, but when I request it through constructor injection in some other service it creates a new object again. Shouldn't it return the first object that it created while startup in Program.cs?
Note : This behavior is only if I request service in the program.cs other than that it returns the same object, even if I request it using IServiceProvider.GetRequiredService();
i have tested the same scenario in dot net 5 web api as well in which i register the service in ConfigureServices method of Startu.cs file
services.AddSingleton<ITest, Test>();
and request the service in Configure method like this
var test = app.ApplicationServices.GetRequiredService<ITest>();
and when i request it in constructor in some other service it will return the same object.
Why?
In your starup file, you don't have a service provider yet. You only have the Services property that allows you to define your services.
Since you want to instantiate one, you call builder.Services.BuildServiceProvider() which builds a service provider for you, that you then use to get a service. Inside that service provider, your service lives as singleton.
Then, you proceed in your application and the framework, being happy that you defined your services, then builds it's own service provider. Which you can access via app.ApplicationServices. That one, too, has a single instance of your class, since it's a singleton.
And from now on, since all your services and controllers use the service provider created by the framework, not the one you created manually in startup, all of them will get the same instance.
I cannot get an HttpClient with AuthorizationMessageHandler working.
I have a project set up using the Microsoft.AspNetCore.Components.WebAssembly.Authentication package, and wired up for OIDC. That's working fine. Now, I want to make an http call to an API in another domain, using the access token provided during the OIDC authentication.
Based on https://learn.microsoft.com/en-us/aspnet/core/blazor/security/webassembly/additional-scenarios?view=aspnetcore-5.0#typed-httpclient, this should be a simple task, but I'm having all sorts of problems with the service collection. Here's what I have to set up a typed HttpClient:
builder.Services.AddScoped<AuthorizationMessageHandler>();
builder.Services.AddHttpClient<IAuthorizationClient, AuthorizationClient>(client => client.BaseAddress = new Uri(authUrl))
.AddHttpMessageHandler(sp => sp.GetRequiredService<AuthorizationMessageHandler>().ConfigureHandler(new[] { authUrl }));
The issue here, for example, is that AuthorizationMessageHandler requires an IAccessTokenProvider in the constructor, which Blazor provides as a Scoped service. However, the HttpClientFactory is registered as a singleton service. When the HttpClientFactory tries to activate an instance of AuthorizationMessageHandler, it fails with the following error:
Cannot resolve scoped service 'Microsoft.AspNetCore.Components.WebAssembly.Authentication.AuthorizationMessageHandler' from root provider.
Registering AuthorizationMessageHandler as a Singleton, I get:
Cannot consume scoped service 'Microsoft.AspNetCore.Components.WebAssembly.Authentication.IAccessTokenProvider' from singleton 'Microsoft.AspNetCore.Components.WebAssembly.Authentication.AuthorizationMessageHandler'.
Registering AuthorizationMessageHandler as a Transient, I get:
Cannot resolve 'Microsoft.AspNetCore.Components.WebAssembly.Authentication.AuthorizationMessageHandler' from root provider because it requires scoped service 'Microsoft.AspNetCore.Components.WebAssembly.Authentication.IAccessTokenProvider'.
I'm out of ideas on how to get this to work. All the examples in the referenced link above don't appear to work.
I've tried this with both net5.0 and net6.0, with the same result.
Hi I have a use case that would be desireable to gain access to IServiceProvider before a function invoke in azure function project.
Attempts:
Using a IWebJobsStartup cs file, I am able to access the serviceCollection before a function invoke. at the end I have attempted this code
var serviceProvider = services.BuildServiceProvider();
serviceProvider.GetRequiredService<IAccountAPITests>();
with in error message "System.InvalidOperationException: 'Unable to resolve service for type 'Microsoft.Azure.WebJobs.Script.IFileLoggingStatusManager' while attempting to activate 'Microsoft.Azure.WebJobs.Script.Diagnostics.HostFileLoggerProvider'.'"
The only time I can access IServiceCollection so far is with in my funciton
public TestAutomationFunction
(
IServiceProvider rootServiceProvider
)
{
_integrationTestService = rootServiceProvider.GetRequiredService<IIntegrationTestService>();
}
This works fine, But the issues is functions are scoped, and thus anything that is resolved with in it will be tied to its same scope.
I did my best to draw a viso of why I dont have this problem in ASP.net and why i do in functions.
I would like to either access IServiceProvider Before a function invoke to ensure my services are not in the same scope. Or after the function is invoked resolve my services with in a spereate scope.
I can of course just change Package X singleton to a scoped, but my use case is not so simple as its deep in my stack i would have to do that all the way down.
This doenst quite answer my question but it makes my question a mute point.
"Do not resolve a scoped service from a singleton. It may cause the service to have incorrect state when processing subsequent requests. It's fine to resolve a singleton service from a scoped or transient service."
https://learn.microsoft.com/en-us/aspnet/core/fundamentals/dependency-injection?view=aspnetcore-3.0#service-lifetimes
I am going to have re work my stack to not allow this to happen, after that I wont have to worry about this issue.
I have the following scenario:
I am using castle windsor component activator to create and destroy the scope for the WCF.
I have a WCFServiceActivator that extends Castles DefaultcomponentActivator and implements the InternalCreate and InternalDestroy to call BeginScope and Scope.Dispose() for the service.
WCF session is defined as per request
I implemented a ErrorHandler class and defined the ProvideFault and HandleError
In the handle error I want to send exception metrics to ApplicationInsights, but when I use castle to provide some factory I get no scope, since it was already destroyed after the provide value runs and the response is sent to the client.
Basically when the HandleError method executes, the scope created by the activator was already destroyed due to the perWcfRequestLifecycle.
I was wondering on maybe creating a new Castle LifecycleStyle that wraps a higher layer of the wcf but I don't know if it is possible.
Does someone have a solution for this scope issue?
In Simple Injector documentation is sentence: "A new instance of the service type will be created for each request (both for calls to GetInstance and instances as part of an object graph).".
I'm little bit confused, what request means? - Is it request like http request or it is request to resolve service (instance) from container?
In part of singleton is term lifetime; lifetime is defined by container.Options.DefaultScopedLifestyle = new WebApiRequestLifestyle();?
By default Transient is used which means every time you request the type a new instance will be created.
You can also use Web Request if you want to reuse the instance for the whole web request.
http://simpleinjector.readthedocs.org/en/latest/lifetimes.html#perwebrequest