Unit test to ensure all required services are added to the .Net Core DI container - asp.net-core

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) ?

Related

Using global state in ASP.Net Core

In my current Asp.Net application I am finding a number core services that are slowly spreading throughout the application through the use of Dependency Injection. One of those services is the need to know who the current authenticated user is. I have a UserService that encapsulates the logic for getting the CurrentUser, but it seems like I am injecting this same service almost everywhere in my application. Is there a different method I could be using for accessing this Global service without constantly growing my constructors to inject yet another object into my classes? (of course I still want to maintain testability)

Can a BackgroundService run indefinitely in ASP .NET Core 3.1?

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

Zend Framework 3 singletons

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.

Unit testing, IoC, DI and mocking objects within a WCF service

I have a WCF service (INTWCF) that consumes another WCF service (EXTWCF). EXTWCF exposes 5 operations, will be hosted on an external app server (in a DMZ), and implements message and transport level security.
INTWCF will be hosted on an internal app server, does not implement any security, hosts two individual services with approx 30 operations - a number of which are called by the operations on EXTWCF (along with various other domain level applications), depending on various parameters passed in (EXTWCF contains simple logic to determine which operations on INTWCF should be called).
EXTWCF implements INTWCF using IoC and DI.
Using TDD, I would like to write my initial unit tests for the operations exposed on EXTWCF. I would therefore like to mock up INTWCF using Moq. I would have thought that I should mock up and inject INTWCF in to the unit testing project, but I've read (in quite a few places) that IoC and DI should not be used during unit testing due to the additional testing dependencies they introduce.
Am I being fed incorrect information, or is there another way to approach this problem? Is mocking appropriate for this situation? Seeing as though my unit tests will be accessing the operations on EXTWCF, they will not know about INTWCF. This seems to me to be a perfect case for DI?
I'm using Ninject for IoC and DI; if DI is the answer, does Ninject provide a bootstrapper / plugins for unit testing? I'm not familiar with any, and don't see anything on their web page?

Autofac: Is it possible to pass a lifetime scope to another builder?

Problem:
I am building a four layer system with Ui, ServiceLayer, BizLayer and DataLayer. In line with good practice the ServiceLayer hides the BizLayer and DataLayer from the Ui, and of course the ServiceLayer doesn't know what the Ui Layer is.
My implementation is a single .NET application with each layer in its own assembly. I am using Autofac.MVC3 in my MVC3 Ui layer to do all the resolving classes used in a web request. I also include standard Autofac in my ServiceLayer so that it can handle the registration of all other layers in my application. At system startup I call a method to register all the types with Autofac. This does:
Register the lower levels by calling a module inside the ServiceLayer. That handles the registration of itself and all other assemblies using the standard NuGet Autofac package.
Then the Ui layer uses the NuGet Autofac.MVC package to register the various controllers and the IActionInvoker for Action Method injection.
My UnitOfWork class in my DataLayer is currently registered with InstancePerLifetimeScope because it is registered by the ServiceLayer which uses plain Autofac and knows nothing about InstancePerHttpRequest. However I read here that I should use InstancePerHttpRequest scope.
Question:
My question is, can I pass a lifetime scope around, i.e. could the MVC layer pass the InstancePerHttpRequest down to the service layer to use where needed? Alex Meyer-Gleaves seemed to suggest this was possible in his comment from this post below:
It is also possible to pass your own ILifetimeScopeProvider implementation to the AutofacDependencyResolver so that you can control the creation of lifetime scopes outside of the ASP.NET runtime
However the way he suggests seems to be MVC specific as ILifetimeScopeProvider is a MVC extension class. Can anyone suggest another way or is InstancePerLifetimeScope OK?
InstancePerHttpRequestScope is in fact a variant of InstantPerLifetimeScope. The first one only works in a request. If you want to execute some stuff on a background thread, it won't be available.
Like you I'm using autofac in as.net mvc and multiple app layers. I pass around the Container itself for the cases where I need to have a lifetime scope. I have a background queue which executes tasks. Each taks pretty much needs to have its own scope and to be exdecuted in a transaction. The Queue has an instance of IContainer (which is a singleton) and for every task, it begins a new scope and executes the task.
Db access and all are setup as INstancePerLifetimeScope in order to work in this case and I don't have aproblem when I use them in a controller.
With the help of MikeSW, Cecil Philips and Travis Illig (thanks guys) I have been put on the right track. My reading of the various posts, especially Alex Meyer-Gleaves post here, it seems that InstancePerLifetimeScope is treated as InstancePerHttpRequest when resolved by the Autofac.MVC package, within certain limitations (read Alex's post for what those limitations they). Alex's comment is:
Using InstancePerHttpRequest ensures that the service is resolved from the correct lifetime scope at runtime. In the case of MVC this is always the special HTTP request lifetime scope.
This means that I can safely register anything that needs a single instance for the whole htpp request as InstancePerLifetimeScope and it will work fine as long as I don't have child scoped items. That is fine and I can work with that.