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.
Related
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.
First at all thanks to all for sharing all the knowledge with the community.
I currently have a Silverlight application that consumes some WCF services. These WCF services use a custom authorization policy which expect an Identity with roles to authorize or not.
In this application all is working fine. I create a channel with the WCF and the Identity is passed from the client to the server.
The problems come when I tried to consume those WCF services from another ASP Net MVC application. I have tried to replicate the web.config in this new application, to maintain the configuration and try to make it easier.
In this new application when I look in the System.Web.HttpContext.Current.User.Identity variable in my IAuthorizationPolicy class, it is empty and the authorization fails.
So the next test that I did was host the WCF in this new application, to avoid authentication between sites. I perform a FormsAuthentication in the site and I create a cookie to store the user information, when I navigate between pages the System.Web.HttpContext.Current.User.Identity has value in my HttpModule class, but when I call to the WCF service this HTTModule class has not value in the System.Web.HttpContext.Current.User.Identity variable.
I am stuck because I do not understand this behavior.
If in my HttpModule class always return a new fixed GenericIdentity, it works fine when I consume the WCF services hosted in the own application.
If I consume the services hosted in the original application it does not work although I return the new GenericIdentity in the HttpModule.
I've spent some days with this issue so I need your kindly assistance. I read a lot about WCF architecture but I need a clue from someone.
Thanks in advance.
I am hosting a WCF service library in an ASP.net web application, which also needs to consume it. What is the best way to do so? Should I create a client proxy and invoke the service that way or is there a way of directly calling it? (the library is a project reference after all, and I guess doing so would be faster)
Since your WCF service library is a project reference for your web application, you could just instantiate the service directly without creating a client proxy. This approach would indeed be faster since you wouldn't be going through the serialization and deserialization that WCF does. However, you may wish to create a client proxy and access the service that way. This approach would be useful if there's any chance you may at some point host the service outside of your web application. If you were to end up moving the service, you would just need to update the endpoint address in your web application's web.config file.
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.
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.