Hello,
I was reading about the new experimental feature of Application being now an IServiceProvider, in which on can AddService and GetService. I was wondering if and how can one use extensions like services.AddDbContext<DataEF>(), where DataEF is a class inheriting from EntityFramework DbContext. Here, services is an IServiceCollection. I would expect someting like
IServiceCollection services = Application.GetServices();
services.AddDbContext…
but there seems to be no such GetServices() method. What is the alternative?
Best,
Alex
There is no GetServices() in https://docs.microsoft.com/en-us/dotnet/api/system.iserviceprovider. You cannot use AddDbContext there since it’s not part of that interface and not in our service container. The code snippets you saw probably use this
public class Startup
{
public void ConfigureServices(IServiceCollection services)
=> services.AddDbContext<EntityContext>();
}
You can use that one. However AddDbContext() is an extension from MS in nuget. You can simply add a DbContext using AddService() or add a simple class that contains a db context. The ASP.NET Core service container doesn’t support session-scoped services. In any case, it all depends on what you are trying to do.
What do you expect services.AddDbContext(data) to do? Create a new db context on each request? Create one db context shared across all sessions? Recreate it for each session? If you setup a smalt test case using services.AddDbContext(data) that shows what you want to achieve we may be able to help more.
Hi Luca,
I think what I would like to do, is access the ASP.Net ServiceProvider, created and loaded in ConfigureServices, from within a Wisej UserControl. How can we do this? How do I get hold of it, let’s say, in the click event of a button?
Alex
I provided a sample in the answer.
For “working all together” I have no idea what it would mean. A stateless webapi is different from a view controller and very different from a stateful wisej component. An api call is just a url handled by an handler. You can respond to the http request in many ways, all outside Wisej scope.
If you want to create and destroy a dbcontext, the using pattern is one way. If you want to save it for the session, then you can use the Application.Session object, if you want to have it automatically created on demand and automatically disposed use the new Application.AddService(). If you want to use any other .NET service container it’s also fine.
Hi Luca,
Hi Luca, as I was writing this answer I saw you posted a second one, but anyway, this is what I was writing:
Yes, this is the one, from ConfigureServices. I’ve been using ConfigureServices in ASP.NET WebAPI projects lately and I’ve seen things like services.AddDbContext, services.AddMediatR, services.AddCors etc, which, I suspect, do more than just AddService(Interface).
I’m also trying to get my head around the difference between WebAPI and WiseJ projects. As I understand it, in WebAPI one has a call to a Controller, which is instantiated on the spot using the injected dependencies in its constructor, e.g. a dbContext, does its job and gets disposed. And at the next call, this is repeated. On the other hand, in WiseJ, there is a Form, UserControl, whatever that is created once and is there “waiting”, so I don’t know if the approach of injecting a DbContext to the Form is correct, or it would be better to use a using(var db = new DbContext()) on the click of a button. Which soon gets disposed.
I could use the ConfigureServices to create the IServiceProvider of the ASP.Net application, but then how is this accessible from a Wisej UserControl?
It would be nice if you could provide an example of how all these can work together.
Best,
Alex
Hi Alex, I looked into AddDbContext() a bit more. It looks like it’s added as an extension to the aspnet container because the default implementation doesn’t support callbacks or custom initialization so they had to add AddDbContext() accepting an options instance. This way they are able to create a new customized DbContext according to the scope. Another problem is that the scope in aspnet core is never the session. At the most you can scope to the http request: i.e. each click creates a new db context.
https://docs.microsoft.com/en-us/ef/core/dbcontext-configuration/
Out service container supports custom initialization and supports the session scope. There is no need to add another method, AddService is all you need. You can of course use AddDbContext() with the aspnet container if you want to destroy and recreate the dbcontext on every request. Otherwise you can use:
Application.AddService(typeof(DbContext), (t, s) => { return new DbContext("connection string"); }, ServiceScope.Session); var dbc = (DbContext)Application.GetService(typeof(DbContext));
Or use your derived class, or change the scope, or register a created instance, or register just the type (wisej will create it on demand), etc. If you want to destroy and recreate the db context on every request let me know, we can add ServiceScope.Request. Consider that everything that coming from the browser is a request.
Please login first to submit.