I want to be able to reload my Swagger configuration without redeploying my service.
So I'm trying to use an IOptionsSnapshot directly in the Startup.ConfigureServices() method :
public void ConfigureServices(IServiceCollection services)
{
services.Configure<SwaggerSettings>(Configuration.GetSection("BaseTemplate:Swagger"));
var swaggerSettings = new IOptionsSnapshot<SwaggerSettings>(); //get an instance
//Configure Swagger
}
I guess that the Startup.ConfigureServices() is called only once when the application is starting ?
Is there any workaround to use and reload a IOptionsSnapshot in the the Startup.ConfigureServices() ?
Yes, the Startup.ConfigureServices() is called only once when the application is starting.
Is there any workaround to use and reload a IOptionsSnapshot in the
the Startup.ConfigureServices() ?
Do you mean you want to create the service instance each time they're requested from the service container or once per client request (connection)? If that is the case, you could try to use AddTransient method or AddScoped method to register the service. Code like this:
services.AddScoped<IMyDependency, MyDependency>();
More detailed information, see:
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.
Reference: Dependency injection in ASP.NET Core and Service lifetimes.
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.
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.
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. :)
I am not sure this is even possible to be honest,
I am wondering if there is a way of removing the use of the config file without having to override the creation of the client proxy. Let me give an example:
In a client app we have a WCF DAL project. This is a wrapper for their WCF Server for the client app to consume. At present the client app would need all the bindings and endpoints given in the config file and would normally (in our projects) do something like the following to wrap the WCF service:
public MyObject GetMyObject(int id)
{
using(var service = new MyObjectDataServiceClient())
{
return service.GetMyOBject(id);
}
}
This would create the call to the server and get an object back. If the client app didn't have the bindings and endpoints it would blow up. We could change each creation of the data service client to create the binding and endpoint, or create our own chanelfactory to do this for us but this means changing the current WCF DAL layer code.
My goal is to try and create a way of inserting a process into the WCF DAL layer that will handle the bindings and endpoints without the consuming code having to change, whilst removing the need for the config file.
My thoughts so far were to try and use a TT file so that it would create a partial class of the data service client and override the channel factory part. This failed because of the constructor call for the data service client goes straight into the abstract class (System.ServiceModel.ClientBase<T>) and tries to get the config stuff out. I could not find a way of stopping it looking in the config via this partial class and not changing the WCF DAL service layer.
If you have the binding and the endpoint at the DAL, you can use a different constructor of the client class (one which takes the binding + endpoint address). That constructor completely bypasses configuration, so you don't need to have anything in config.
I have a WCF service hosted in IIS 7. It takes some minutes until this service finish to load its data and ready for external calls. Data loads in internal thread. The problem is that from IIS point the service is ready just after it was activated (by some call), and it process a request without waiting for data to be loaded.
Is it possible to tell IIS that the service is still loading and make this service unavailable for requests? No problem if such request will throw an exception.
You could invoke the initialization logic synchronously in the service's default constructor. The service operations won't be invoked until the service instance has been created, which will only happen after the initialization has completed. In the meantime clients simply won't receive a response.
Here's a quick example:
public class MyService : IMyService
{
public MyService()
{
// Blocking call that initializes
// the service instance
this.Initialize();
}
public void GetData()
{
// The service operation will be invoked
// after the service instance has been created
// at which point the initialization is complete
}
private void Initialize()
{
// Initialization logic
}
}
If the initialization logic is expensive, you should consider making your service run as a singleton, so that the price is paid only at the first request. Alternatively you could store the data loaded during initialization in a centralized cache. This way it can be made available to multiple service instances while still having to load it only once.
If the initialization logic is shared across multiple services, you should consider implementing it once in a custom ServiceHost by overriding the OnOpening method. Since you're hosting your services in IIS, you would then also need to implement a custom ServiceHostFactory to create instances of your ServiceHost.You can read more about this approach in this MSDN article.
Found this new feature described in "ASP.NET 4 and Visual Studio 2010 Web Development Overview": http://www.asp.net/LEARN/whitepapers/aspnet4/#0.2__Toc253429241
The problem that it's requires IIS 7.5 running on Windows Server 2008 R2, but works with ASP.NET 2.0+