I have been looking into the following code(I know it is ADAL and not MSAL, but was interested in the DI).
https://github.com/juunas11/azure-ad-on-behalf-of-sample-aspnetcore/blob/master/ApiOnBehalfSample/Startup.cs
The dependencies are registered as Singleton. Is that right?
Is there an issue in them being registered as Scoped?
What is the correct way of deciding the lifetime of the dependencies?
Update:
In the above code uses ADAL to authorize the user and get the user profile using Graph API.
There are 3 dependencies registered in the Startup.cs class,
services.AddSingleton<IGraphApiService, GraphApiService>();
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
services.AddSingleton<IAuthenticationProvider, OnBehalfOfMsGraphAuthenticationProvider>();
So I understand the httpcontextaccessor should be a singleton.
The IAuthenticationProvider (which is used to create Graph Client), should that be singleton?
Also can the IGraphAPIService which calls the Graph API endpoint and returns user profile info be scoped?
Hey here's a quick overview about Dependency Injection Service Lifetimes on .NET from Microsoft official article. Hope it helps you to decide.
Transient
Transient lifetime services are created each time they're requested from the service container. This lifetime works best for lightweight, stateless services. Register transient services with AddTransient.
In apps that process requests, transient services are disposed at the end of the request.
Scoped
For web applications, a scoped lifetime indicates that services are created once per client request (connection). Register scoped services with AddScoped.
In apps that process requests, scoped services are disposed at the end of the request.
When using Entity Framework Core, the AddDbContext extension method registers DbContext types with a scoped lifetime by default.
Singleton
Singleton lifetime services are created either:
The first time they're requested.
By the developer, when providing an implementation instance directly to the container. This approach is rarely needed.
Every subsequent request of the service implementation from the dependency injection container uses the same instance. If the app requires singleton behavior, allow the service container to manage the service's lifetime. Don't implement the singleton design pattern and provide code to dispose of the singleton. Services should never be disposed by code that resolved the service from the container. If a type or factory is registered as a singleton, the container disposes the singleton automatically.
Register singleton services with AddSingleton. Singleton services must be thread safe and are often used in stateless services.
In apps that process requests, singleton services are disposed when the ServiceProvider is disposed on application shutdown. Because memory is not released until the app is shut down, consider memory use with a singleton service.
Related
I use singleton manager in rest api method.
[HttpGet("GetUserData")]
public JsonResult GetUserData()
{
//Singleton class in rest api method
AuthManager manager = AuthManager.GetInstance();
}
Server will publish auth key when session(user) request login.
And Server will save this by Dictionary.
The key is authkey and value is user info which include session id.
And my rest api must be used by logged in and authorized user, so i must check first session's authorized when the session request by rest api.
So all rest api must be access that singleton auth manager class.
But if it is not thread safe, then i must use lock (And it makes me very terrible).
Does asp.net core's controller method (view method or rest api) is thread safe?
Self Answering.
No it's not thread safe to use singleton in mvc controller.
You must lock to synchronize the thread.
Using something like a DI to inject your dependencies at the constructor level would help. netcore has its own built in container or you can use something like AutoFac
I have a WCF service that is hosted in a windows service. It shares the same libraries as an ASP.NET project. The WCF service is used to process long running operations that I don't want the ASP.NET site running. I'm using Autofac to handle dependencies in both the ASP.NET and WCF project. Since I'm using ASP.NET, I'm using the InstancePerLifeTimeScope() method on all registrations. Since these same registration modules are also used in the WCF service, I was hoping they would create instances per WCF method call, but that is not happening. Is there a way to get Autofac to consider an object's lifetime scope the same as the life time as a service call?
I hope that makes sense.
Assuming you are using the Autofac service hosting mechanism, if you register your service-related objects as InstancePerDependency and set your InstanceContextMode to PerCall, each call should get its own dependencies resolved. Autofac doesn't have an explicit "per call" lifetime setting for WCF.
I'd like to be able to create standard POCO service that I can use in two distinct workflows:
in-process i.e. consumed by my ASP.NET webforms application
remotely via an exposed WCF endpoint to be consumed by other applications
Is there a way to re-use the same service and its return data types in both scenarios above? Ideally, my core service and data types would not have to be decorated with WCF specific attributes and I could add these attributes in some kind of WCF facade layer.
Thanks!
Since .NET 3.5 you don't need to decorate your data objects with WCF related attributes (DataContract, DataMember). If you don't use them default serialization will be used - all properties with public getter and setter will be serialized (also class has to have public parameterless constructor).
Sharing "service" layer works exatly as you have described. You create business service layer which exposes functionality. This functionality is consumed in-process by your ASP.NET application. Than you create wrapper layer which is marked with WCF related attributes and exposed as WCF service. Your WCF layer can be handled as facade and compound several business calls to single web service call.
We have WCF based SOA architecture and ASP.NET web application consume the services hosted. Within each method that needs service call, we create a proxy instance and close when the results are returned. The binding is basicHttpBinding. By default InstanceContextMode is per session, do we need to change this to Percall as we do not require any state full calls in the application. Does this improve any performance?
Should I access the asp.net membership class from the controller and pass the results to the service layer, or access it directly from the service layer?
I'm torn because on one hand this seems like business logic that should be handled in the service layer, but I don't want to tie the service layer to the web namespace as this might become an windows app down the road.
the answer, use IoC to create a membership interface that the service layer uses. the website's implementation can use the web namespace. And the windows app can have a different implementation. and since you can inject that dependency, your service layer doesn't have to change :-)
ASP.NET Membership is Web-specific, so that should be accessed in the Controller. MHO is that the service layer should not be hard-wired to the web. So for adding/removing users, do that via the Controller.
OTOH, in the service layer, you can read Thread.CurrentPrincipal.Identity, which is non-web-specific, but happens to be entirely compatible with ASP.NET Membership. So if you only need to get the current user you can do that without voilating separation of concerns.
Is it really a problem to use System.Web? It's no different than tying it to System.Configuration, or System.IO. Any application can make use of it, whether it's "offline" or not.
I routinely tie my web apps to assemblies that are more classically though of as "winforms" assemblies, to get access to useful collection objects and such.