I'm sure this is obvious but I haven't been able to find a very specific clean answer to the lifetime of a container in a IIS 7.5 hosted WCF service.
If the container lives in my service code, it would be created on every request unless InstanceContextMode is set to single? (I know bad idea)
If I configure WCF using ServiceHostFactory and IInstanceProvider to use a container to resolve the service object on every call how would the InstanceContextMode work? Wouldn't it depend on the lifetime policy used by the container?
If its a singleton created in the factory is that sufficient such that the container won't reinitialize on every call?
Thanks
You should host the container in a custom ServiceHostFactory since there's only a single instance of the ServiceHostFactory for a given WCF service.
This ensures that the container itself is a single instance, thus enabling it to effectively manage lifetime of all components.
Related
I want to use background tasks in asp.net core.
I found helpful documentation https://learn.microsoft.com/en-us/aspnet/core/fundamentals/host/hosted-services?view=aspnetcore-6.0&tabs=visual-studio
I wonder why their lifetime apparently is scoped: Hosted service that activates a scoped service. The scoped service can use dependency injection (DI).
What is a scope in this context?
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.
While I do understand what that means for e.g a standard http get request to an api,
I do not understand the meaning for a background worker.
Imho it would make more sense to have a singleton backgroundworker. I certainly do not want to have multiple instances running at a time in my application.
Another thing is DI in background workers which apparently differs fron standard services:
To use scoped services within a BackgroundService, create a scope. No scope is created for a hosted service by default.
I cannot confirm that:
services.AddHostedService(x => new DataPersister(x.GetRequiredService<IAsyncDocumentSession>(), x.GetRequiredService<ILogger>()));
seems to work just fine.
You have to read the sentence “Hosted service that activates a scoped service” within its full context:
This article provides three hosted service examples:
Background task that runs on a timer.
Hosted service that activates a scoped service. The scoped service can use dependency injection (DI).
Queued background tasks that run sequentially.
(from “Background tasks with hosted services”, emphasis mine)
So it is not the case that hosted services have a scoped lifetime. All hosted services added using AddHostedService() are actually added with a singleton lifetime, ensuring that there will only ever be a single instance of it.
What the article refers to is the situation when you need to consume a scoped service, like a database connection, within a hosted service. Since you cannot inject scoped dependencies into a singleton service, you will need a different solution there. And the solution usually involves having the singleton service (the hosted service in this case) create a service scope itself from which it can then retrieve the scoped dependency.
I went into more details about the service scopes in this recent answer to a similar question if you are interested.
All,
I have developed a WCF Web Service and hosted it in IIS7.5. The service behavior is instanceContextMode=InstanceContextMode.PerSession and hence IIS creates an service instance during the first requests and creates as many instances as the number of requests.
But there is a requirement to cache some of the application data upfront before the service is invoked ie., similar to static initialization.
I don't want to disturb the service behavior attributes but want to achieve the static initialization.
I did try to use CustomServiceFactory and take up the load of creating service factory instances myself. But looks like the IIS will create the service factory as well during first request or I am not sure on this part.
So, I would like to know how to create the service instance / service factory instance when the application is deployed in IIS or during IIS restart?
Any help is much appreciated!
We are using the auto-start feature of AppFabric to initialize the services on application startup/app pool recycle. It invokes each service inside the application once during application start.
A little background info -
I'm trying to host a RESTful WCF service on Azure. As I understand, unless I have the ASP.NET type hosting on the role, I don't really need the global.asax class (which has the application_start method).
From basic prototyping, all I needed was the svc file and the implementation behind it and it automatically gets initialized on role startup (I mean, hosted up on IIS).This is great because I need no extra code other than web.config and my service is up and running. I don't need to create a new service host and start listening on it, etc. I'm able to deploy the role and POST messages to my service.
The problem -
I have custom logging and initialization classes implemented that I need to initialize when my service starts up. I configured my service to be a singleton and I'm not sure where I should put my custom initialization components.
Without an explicit application start method and my service configured as a singleton, can I assume that when the first request comes in, my service constructor gets called? (along with all my custom initialization?).
can I assume that when the first request comes in, my service constructor gets called?
Yes, but you should ask yourself whether you really want your service to run as a singleton. If you're happy with this then it will work fine; if you don't want it to run as a singleton then you should look into Russell's answer using a custom factory.
Look at Should WCF service typically be singleton or not? for some discussion about whether WCF services should be singletons. You need to decide for your situation, but generally WCF services are not singletons unless they need to be.
To implement a custom factory, see this MSDN link Extending Hosting Using ServiceHostFactory. As the link describes, extend the service host factory like so
public class DerivedFactory : ServiceHostFactory
{
public override ServiceHost CreateServiceHost( Type t, Uri[] baseAddresses )
{
return new ServiceHost(t, baseAddresses )
}
}
And then specify your factory in the ServiceHost directive
<% # ServiceHost
Service="MyNamespace.MyService"
Factory="MyNamespace.DerivedFactory" %>
You're looking for ServiceHostFactory. You can add a part to the SVC file to use a factory, where you can do any logging etc. you may need.
I have used this in the past to start a background worker to launch a separate thread for some background work.
http://msdn.microsoft.com/en-us/library/system.servicemodel.activation.servicehostfactory.aspx
Hope this helps you get where you need to be. :)
Where is the best place to put code for when a WCF service is just started up? Similar to Page_Load in a web application.
The service implementation constructor would be the obvious place but it also depends on your hosting model
1) run once code: IIS hosting = global.asax; self-hosting = Main / OnStart
2) run once per service instance: constructor of service class
3) Something more exotic: implement IInstanceProvider
In the class constructor of the service implementation.
Honestly the best place is the constructor and/or static constructor for your service class (for static members). There is no other WCF specific lifecycle event that will notify your service implementation when it's being created by the service host.
Now, if you're talking about the creation of services generically, that would mean you're willing to hook into the WCF runtime and there you can do things like get in the middle of the instance creation with a custom IInstanceProvider implementation.
I have a dependency injection container setup in my application and I'm thinking that composing the container every time a WCF service request comes in is going to be inefficient.
Can somebody explain to me, for an http/IIS hosted WCF service, what the lifecycle of the service is? If I can figure this out, I can make an educated decision on where the container is to be stored, instantiated, destroyed, etc.
If your InstanceContextMode is PerCall, the service class will be created from scratch for every incoming request, and then disposed of when it's done.
If your InstanceContextMode is PerSession, the service class will be created and used to service one given client for the duration of the session (or until an "InactivityTimeout" is encountered, or an error occurs).
If your InstanceContextMode is Single (singleton), the service class will be created when the first request comes in and will stay in memory as long as requests keep coming in, as long as no error occurs and no inactivityTimeout is reached.
So, there you have it! Of course, the concurrency mode (for PerSession and Single services) will also come into play to make things just a tad more "interesting"
As you mention that you were trying to integrate WCF service instantiation with a dependency injection container, I'd just like to say that I've had a very positive experience using the Castle WCF Integration Facility to do just that.
It's specific to the Castle Windsor dependency injection container but with it being open source you can look inside and understand some of the challenges and solutions provided.
It depends on your ServiceBehavour.
Specifically this and this.