I have an ASP.NET Core 2.2 app using EF Core 2.2.
I have some background worker threads which I start in ConfigureServices(). These threads depend on the DbContext and on other services which I register in ConfigureServices().
I found that when I try to use Add-Migration, the EF tools cause these threads to run, which in turn throw exceptions in the Add-Migration output because the threads try to access a database object that does not yet exist.
It appears the migration is created successfully, however, it makes using the tooling difficult because it appears to fail (exceptions in output, process does not exit, etc).
Some options I see to avoid this:-
a) Somehow detect in ConfigureServices() that the database does/does not match the context (i.e. is "up to date") and act accordingly.
b) Start my worker threads somewhere else that will not get invoked when my app is run by the EF tools. Keeping in mind that starting these threads require a ServiceProvider with the same scope I'm building in ConfigureServices().
c) Detect in my app that I'm being called by the EF tools and avoid launching the worker threads.
I'd appreciate any advice on the most appropriate strategy and the best method of achieving it.
EF Core tools use different strategies for creating derived DbContext, explained in the Design-time DbContext Creation section of the documentation.
Looks like currently you are using From application services. But according to the problem explanation, the most appropriate in your case seems to be From a design-time factory:
You can also tell the tools how to create your DbContext by implementing the IDesignTimeDbContextFactory<TContext> interface: If a class implementing this interface is found in either the same project as the derived DbContext or in the application's startup project, the tools bypass the other ways of creating the DbContext and use the design-time factory instead.
Related
I am constructing a web service that receives data and updates it periodically. When a user pings the service, it will send specific data back to the user. In order to receive this data, I have a persistent that is created on startup and regularly receives updates, but not at periodic intervals. I have already implemented it, but I would like to add DI and make it into a service. Can this type of problem be solved with a BackgroundService or is this not recommended? Is there anything better I should use? I originally wanted to just register my connection object as a singleton, but since singletons are not initialized on startup, that does not work so well for me.
I thought I would add an answer as so expand on my comment. From what you have described, creating a BackgroundService is likely the best solution for what you want to do.
ASP.NET Core provides an IHostedService interface that can be used to implement a background task or service, in your web app. They also provide a BackgroundService class that implements IHostedService and provides a base class for implementing long running background services. These background services are registered within the CreateWebHostBuilder method in Program.cs.
You can consume services from the dependency injection container but you will have to properly manage their scopes when using them. You can decide how to manage your BackgroundService classes in order to fit your needs. It does take an understanding of how to work with Task objects and executing, queueing, monitoring them etc. So I'd recommend giving the docs a thorough read, so you don't end up impacting performance or resource usage.
I also tend to use Autofac as my DI container rather than the built in Microsoft container, since Autofac provides more features for resolving services and managing scopes. So it's worth considering if you find yourself hitting a wall because of the built in container.
Here's the link to the docs section covering this in much more depth. I believe you can also create standalone service workers now, so that might be worth a look depending on use case.
https://learn.microsoft.com/en-us/aspnet/core/fundamentals/host/hosted-services?view=aspnetcore-3.1&tabs=visual-studio
Edit: Here's another link to a guide an example implementation for a microservice background service. It goes a little more in depth on some of the specifics.
https://learn.microsoft.com/en-us/dotnet/architecture/microservices/multi-container-microservice-net-applications/background-tasks-with-ihostedservice#implementing-ihostedservice-with-a-custom-hosted-service-class-deriving-from-the-backgroundservice-base-class
My team maintains a very large .Net Core 2.1 web site. Lots of controllers, lots of services that get injected into the controllers via constructor injection.
Sometimes due to developer error a service class is no longer added to the DI container during startup. Obviously this leads to an exception when MVC tries to construct a controller that relies on that service (in response to an incoming request).
Problem is that this may affect only some lightly used controller, so our (far from perfect) regression testing doesn't pick up the regression bug. But it is still bound to be picked up by one of our (very demanding) customers.
I though of writing a unit test that would
Instantiate a ServiceCollection class (that implements IServiceCollection);
Call our own method that adds all services to that service collection (the same method used during normal startup);
Find all controllers through reflection, and try to construct them the same way MVC does - by getting dependent services from the DI container.
So my question is:
Does this approach make sense?
Is there an example somewhere that I could use?
Failing an example, how would I achieve 1) and 3) ?
I'm creating a new application in Zend Framework 3 and i have a question about a design pattern
Without entering in much details this application will have several Services, as in, will be connecting to external APIs and even in multiple databases, the workflow is also very complex, a single will action can have multiple flows depending on several external information (wich user logged in, configs, etc).
I know about dependency injections and Zend Framework 3 Service Manager, however i am worried about instanciating sereval services when the flow will actually use only a few of them in certain cases, also we will have services depending on other services aswell, for this, i was thinking about using singletons.
Is singleton really a solution here? I was looking a way to user singletons in Zend Framework 3 and haven't figured out a easy way since i can't find a way to user the Service Manager inside a service, as I can't retrive the instance of the Service Manager outside of the Factory system.
What is an easy way to implement singletons in Zend Framework 3?
Why use singletons?
You don't need to worry about too many services in your service manager since they are started only when you get them from the service manager.
Also don't use the service manager inside another class except a factory. In ZF3 it's removed from the controllers for a reason. One of them is testability. If all services are inject with a factory, you can easily write tests. Also if you read your code next year, you can easily see what dependencies are needed inside a class.
If you find there are too many services being injected inside a class which are not always needed you can:
Use the ProxyManager. This lazy loads a service but doesn't start it until a method is called.
Split the service: Move some parts from a service into a new service. e.g. You don't need to place everything in an UserService. You can also have an UserRegisterService, UserEmailService, UserAuthService and UserNotificationsService.
In stead of ZF3, you can also think about zend-expressive. Without getting into too much detail, it is a lightweight middleware framework. You can use middleware to detect what is needed for a request and route to the required action to process the request. Something like this can probably also done in ZF3 but maybe someone else can explain how to do it there.
I have been writing a WPF DESKTOP application using NHibernate, WPF, Prism and Unity Container but have a problem in terms of Session Management in Services / Repositories and how to do it cleanly through dependency injection using Unity.
Having read Building A Desktop To Do-Application With NHibernate I now have a Session Per ViewModel / Presenter.
However, if I have several services on my viewmodel I have to pass the Session into each and every service which seems cumbersome and not quite right as I want to perform all data access through a repository.
e.g
CustomerMaintenanceViewModel
{
service1.Session = SessionForThisPresenter;
service2.Session = SessionForThisPresenter;
service3.Session = SessionForThisPresenter;
service1.GetAllSomething();
service2.GetAllSomething();
service3.GetAllSomething();
}
Each service is essentially a facade over a repository and I would want each repository for this presenter to be involved in the same session without explicitly setting it.
Any advice on how to handle this would be most appreciated as I am sure there is a solution quite close but I am not sure how to do it.
I suggest you look into uNhAddIns.
It has a full WPF example using MVVM.
I would like to create an Entity Framework 4.0 context when a call is received and invoke to save changes when it finish, (something like JPA).
I think it is a good idea because I can use the state for all the call, It is short and encapsulate enogh to be threadsafe and long enough for caching calls and the context itself.
Any idea how is the best way for implement this?
Yes, definitely, that's the best way to go.
By default and by best practice recommendation, WCF service calls are "per-call", e.g. each requests gets a brand new, dedicated instance of the service class all to itself - no messy multithreaded/concurrency stuff to deal with - just a nice clean execution environment.
With EF 4, the "disconnected" scenario of sending back entities through WCF was one of the (many) areas that the EF team focused on. See some of these resources for more information:
Building N-Tier apps with EF4
More on disconnected Entity Framework
Attaching modified entities in EF4