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
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 have a .NET Core WebAPI my React UI is calling to Authenticate Users. It calls a 3rd Party API for this. Everything works fine but we have started to do Performance testing on it and it is not scaling well when we ramp up the Users attempting to log on concurrently. (taking 30 secs)
The 3rd Party API we call are saying they are responding in milliseconds.
My API is hosted in Kubertnetes container on AWS. I have added AWS X-ray to the code to try and get further information though I am not really sure on how to interpret the results.
The code is quite straightforward - This is a snippet from MyAuthenticationProvider class (the constructor takes a metric collector (for AWS X-Ray and and securityProvider http client for making the call)
metricCollector.StartCollection("Stage 1");
HttpResponseMessage response = await securityProvider.SendAsync(requestMessage);
metricCollector.EndCollection();
The X-Ray image for the above code is:
Is X-Ray showing that it is indeed waiting 30+ Seconds for this API to return a response and I should reach out to that company for further investigation on there side even though they are telling me all traffic is getting responded too in milli-seconds.
Or could it be how I have defined the http client used in MyAuthProvider class in Startup.cs that is not scaling correctly when the concurrent users ramps up?
This is the code for that in Startup.cs
services.AddTransient<IMyAuthenticationProvider>(ctx =>
{
IHttpClientFactory clientFactory = ctx.GetRequiredService<IHttpClientFactory>();
return new MyAuthenticationProvider(
clientFactory.CreateClient("3RDPARTYAUTHCLIENT"),
ctx.GetService<IMetricCollector>());
});
Another thing I was thing to improve performance is introducing Redis to cache some of these responses as they are getting calling multiple times for different operations but the result will be the same
While you're only creating 1 named HttpClient, you've set the service lifetime of IMyAuthenticationProvider to transient.
This means that essentially you're losing out on most of the benefits of a single HttpClient by creating a new instance of IMyAuthenticationProvider every time something requests for one (which in the best-case scenario, will be synonymous with every client request but not to be mistaken with scoped services).
This can massively slow down your application & may be the cause of the badly performing scaling of the application.
You're trying to clearly use a single HttpClient, which would typically be static or wrapped as a non-static instance inside a singleton class. and is still a good solution for short-lived console applications etc. however in this case I'd allow IHttpClientFactory to resolve the client.
The primary goal of IHttpClientFactory in ASP.NET Core is to ensure that HttpClient instances are created appropriately (taking into account things like DNS changes which a single HttpClient instance won't take care of) while at the same time eliminating socket exhaustion.
Injected HttpClient instances by IHttpClientFactory have a transient lifetime (documentation is conflicting & mentions transient 2x & scoped 1x for some absurd reason) and so I'd set the lifetime of IMyAuthenticationProvider to scoped to allow it to be reused as much as possible.
Having a longer running singleton IHttpClientFactory, in this case, with an injected shorter-lived scoped HttpClient should not be done.
MSFT:
Do not resolve a scoped service from a singleton and be careful not to do so indirectly
While the injected HttpClient object is transient, using the IHttpClientFactory enables pooling of HttpMessageHandler objects that can and will be reused by multiple HttpClient instances.
Try:
services.AddHttpClient<IMyAuthenticationProvider, MyAuthenticationProvider>();
services.AddHttpClient<IMetricCollector, MetricCollector>();
...
services.AddScoped<IMyAuthenticationProvider, MyAuthenticationProvider>();
public class MyAuthenticationProvider : IMyAuthenticationProvider
{
private readonly HttpClient _httpClient;
public MyAuthenticationProvider(HttpClient httpClient)
{
_httpClient = httpClient;
}
...
}
We're all being taught to use Dependency-Injection for coding in ASP.NET Core applications, but all of the examples I've seen so far that related to the retrieval of services via DI relate to situations where the method that has the service reference injected is strictly bound to a specific HTTP request (HttpContext) (e.g. MVC controllers, Routing delegates).
Service location is warned against as an anti-pattern, but I'm not sure on how to obtain a proper service (e.g. DbContext) reference via DI in code that is not bound a specific HTTP request, e.g. code that has to respond to messages arriving over a websocket.
Although the websocket itself is set-up initially with a specific HTTP request, messages will get responses over potentially a long lifetime of the websocket (as long as the user web session lasts). The server should not reserve/waste a DbContext/DB connection over this entire lifetime (this would result in exhaustion quickly), but rather obtain a DB connection temporarily when a message arrives and requires a response; discarding the DbContext/connection immediately afterwards - while the original HTTP request that set-up the websocket in the very beginning of the user-session technically is still there.
I haven't been able to find anything else but using:
httpContext.RequestServices.GetService(typeof(<MyNeededDbContext>)
This way I use the initial httpContext (obtained via DI when the websocket was set up), but at multiple times after that whenever a websocket message needs a response I can request a transient service object (a DbContext in this example), that may be recycled or pooled after the message response is complete, but while the original httpContext is very much still alive.
Anyone aware of a better approach?
You can create a new service scope to manage the lifetime of services yourself;
IServiceProvider provider = ...;
using (var scope = provider.CreateScope())
{
var context = scope.ServiceProvider.GetService<MyNeededDbContext>();
...
}
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.
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?