How to make the Controller a single instance per application in ASP.NET MVC? - asp.net-mvc

Over time controllers develop a lot of dependencies, and creating an instance of controller becomes too expensive for each request (especially with DI). Is there any solution to make controllers singletons?

Creating instances of controllers is pretty fast and simple operation. What becomes too expensive is creating dependencies for each request. So, what you really need is many controllers which share same instances of dependencies.
E.g. you have following controller
public class SalesController : Controller
{
private IProductRepository productRepository;
private IOrderRepository orderRepository;
public SalesController(IProductRepository productRepository,
IOrderRepository orderRepository)
{
this.productRepository = productRepository;
this.orderRepository = orderRepository;
}
// ...
}
You should configure your dependency injection framework to use same instances of repositories for all application (keep in mind, you can have synchronization problems). Now creating dependencies is not expensive any more. All dependencies are instantiated only once, and reused for all requests.
If you have many dependencies and you are worrying about costs of getting reference to instance of each dependency and providing these references to controller instance (which I don't think will be very expensive), then you can group your dependencies (something like Introduce Parameter Object refactoring):
public class SalesController : Controller
{
private ISalesService salesService;
public SalesController(ISalesService salesService)
{
this.salesService = salesService;
}
// ...
}
public class SalesService : ISalesService
{
private IProductRepository productRepository;
private IOrderRepository orderRepository;
public SalesService(IProductRepository productRepository,
IOrderRepository orderRepository)
{
this.productRepository = productRepository;
this.orderRepository = orderRepository;
}
// ...
}
Now you have single dependency, which will be injected very quickly. If you will configure your dependency injection framework to use singleton SalesService, then all SalesControllers will reuse same instance of service. Creation of controllers and providing dependencies will be very fast.

So first an answer to the original question:
public void ConfigureServices(IServiceCollection services) {
// put other services bindings here
// bind all Controller classes as singletons
services.AddSingleton<HomeController, HomeController>();
// tell framework to obtain Controller instances from ServiceProvider.
services.AddMvc().AddControllersAsServices();
}
As stated in the original question, if controllers have big dependency trees consisting mainly of request Scoped or Transient dependencies then creating them separately for each request may have some footprint on scalability of your application (in Java for example Servlet instances are singletons by default exactly for this reason). While usually CPU and real time needed to create even a big dependency tree is negligible (unless you have some heavy computations or network communication in constructors of your components, which almost never is a good idea for transient or request scoped components), the memory usage footprint is something to reckon with. In case of common DB-Web apps memory is the main factor limiting number of concurrent requests that a single machine-node can handle. If every request has a separate copy of a big dependency tree, together they may consume a significant amount of memory (the other thing to watch for is initial stack size for a new thread, by the way).
The accepted answer 1220560 solves the problem as well, but I would consider it an ugly hack and it has some drawbacks: you need to create this artificial singleton service that will be used by your Controllers either as a service locator or a proxy for other services. If you have just one such singleton object for all your controllers then you are effectively hiding real dependencies of your Controller: for example if someone wants to write a unit-test for your Controller he needs to analyse carefully its implementation to see which dependencies it actually uses, so that he knows what mocks/fakes he needs to provide in his test setup. If later you change your Controller and as a result of your change the subset of services your controller uses changes as well, it is very easy to forget to update the test setup also. This may sometimes lead to bugs that are hard to track. Contrary to this, if your dependencies are declared explicitly as constructor params, you will get a compiler error in the test setup right away. Another thing you can do is to have a separate such a singleton proxy/service locator for each controller, but then it's a lot of hassle basically.
Regardless whether you use the solution proposed by me or the one from answer #1220560 you must be careful when injecting request Scoped dependencies into singleton objects as described in https://learn.microsoft.com/en-us/aspnet/core/fundamentals/dependency-injection#registering-your-own-services right at the end of the "registering-your-own-services" section. You can find possible solutions to this problem here: how to use scoped dependency in a singleton in C# / ASP
Another thing to watch for is concurrency issue: singleton objects may be accessed concurrently by several threads handling different concurrent requests, so make sure to add proper synchronization to any non-thread-safe resources your singleton uses.
edit:
I've just realized the original question was about ASP.NET and this answer is for ASP.NET Core, so it probably won't work for "non-Core".

Related

DDD: Service and Repositories Instances Injected with DI as Singletons

I've recently been challenged on my view that singletons are only good for logging and configuration. And with Dependency Injection I am now not seeing a reason why you can't use your services or repositories as singletons.
There is no coupling because DI injects a singleton instance through an interface. The only reasonable argument is that your services might have shared state, but if you think about it, services should be stand alone units without any shared state. Yes they do get injected with the repositories but you only have one way that a repository instance is created and passed to the service. Since repositories should never have a shared state I don't see any reasons why it also cannot be a singleton.
So for example a simple service class would look like this:
public class GraphicService : IGraphicService
{
private IGraphicRepository _rep;
public GraphicService(IGraphicRepository rep)
{
_rep = rep;
}
public void CreateGraphic()
{
...
_rep.SaveGraphic(graphic):
}
}
No state is shared in service except repository which also doesn't change or have it's own state.
So the question is, if your services and repositories don't have any state and only passed in, through interface, configuration or anything else that's instantiated the same way they then why wouldn't you have them as singleton?
If you're using the Singleton pattern i.e a static property of a class, then you have the tightly coupling problem.
If you need just a single instance of a class and you're using a DI Container to control its lifetime, then it's not a problem as there are none of the drawbacks. The app doesn't know there is a singleton in place, only the DI Container knows about it.
Bottom line, a single instance of a class is a valid coding requirement, the only issue is how you implement it. The Di Container is the best approach. the Singleton pattern is for quick'n dirty apps where you don't care enough about maintainability and testing.
Some projects use singleton for dependence lookup before dependency injection gets populated. for example iBATIS jpetstore if I'm not mistaken. It's convenient that you can access your dependence gloablly like
public class GraphicService : IGraphicService
{
private IGraphicRepository _rep = GraphicRepository.getInstance();
public void CreateGraphic()
{
...
_rep.SaveGraphic(graphic):
}
}
But this harms testability (for not easy to replace dependence with test doubles) and introduces implicit strong dependence (IGraphicService depends on both the abstraction and the implementation).
Dependeny injection sovles these. I don't see why can't use singleton in your case, but it doesn't add much value when using DI.

MVC DI/IoC too many dependencies?

Given this example of an MVC controller; psuedo code...
PostController
{
private IGetPost _getPost;
private ICreatePost _createPost;
private IDeletePost _deletePost;
private IUpdatePost _updatePost;
public ActionResult Get()
{
return _getPost();
}
public ActionResult Create(post)
{
return _createPost(post);
}
public ActionResult Update(posts)
{
return _updatePost(post);
}
public ActionResult Delete(post)
{
return _deletePost(post);
}
}
The question I have is that if any one of the actions on the controller is called, all the dependencies of the controller have instances created for them, which seems like a performance buzzkill. Is there a better way to do this? The only thought I had was to create 4 different controllers each with only a single action, but that seems like overkill. I also thought of calling the DependencyResolver directly in each action, but I am unsure of what the implications for unit testability will be if I do that.
Why is it a performance buzzkill? Have you measured this to be the case? While there's overhead in determining what implementations map to what interfaces, most dependency injection (DI) containers worth their salt will do this mapping once (and usually create compiled code on the fly so that the lookup is as quick as possible) to create the mappings.
It's then just a matter of creating the objects, which would be no different than if you were to use the new keyword.
For general cases, this isn't going to be a performance hit. Considering this is a web application, if you were getting Stack Overflow levels of traffic, then it very well could be an impediment to scaling; each of these operations is cheap, but when multiplied by a factor of millions, in aggregate, it's very expensive, and usually, these are the types of things that could lead to resource contentions, etc.
Assuming that this isn't the case (Stack Overflow levels of traffic), where you very well could be facing a performance issue is in the implementations of the constructors.
If the implementation of those four interfaces (or any number of them) is costly, that's not a function of DI, it's a function of your code and that's something you will get more benefit from optimizing.
The only place where tweaking the dependency injection might be beneficial would be if the construction one or more of those implementations had high overheads, and you had your DI container create one instance for all interface implementations instead of one instance per interface implementation. However, you should only look into lifetime management through the DI layer when you've determined that option is available to you (meaning, having one instance of that class to service all requests is viable; is it thread-safe? Does it hold onto any resources for a very long time? etc.)
If you're truly concerned about this and the above doesn't apply or isn't an option, then yes, you could create a number of smaller controllers, and that might make sense for other reasons; if the actions you are performing are not logically related to each other, they probably should be in separate controllers.
However, looking at the actions you have, it would seem that the logical divide you have is correct.
Long story short, don't try to optimize for performance in places you haven't measured it to be a factor.
That said, whatever you do, do not resolve dependencies inside of your class. If you do, you lose all the benefits of DI, and are tightly binding your class to a DI container (and possibly killing testability while at it).
I'm not sure the performance will really be a problem unless you have a really ridiculous number of dependencies. Either way, it's a good exercise to look at your architecture.
The way we do this is to abstract service level calls out to an external class, called a handler. This is from inspiration from Project Silk. This way, not only are you slimming down your controllers and making them much more manageable, but it avoids this kind of dependency build up.
In this case, you'd have the one controller which, for each action, simply resolves a handler and its dependencies, and executes it. Handlers are defined as small classes with very few (one is common) methods.
class MyController : BaseController
{
public ActionResult Get(int id)
{
return Using<GetItemHandler>().Execute(id);
}
}
class GetItemHandler
{
private IDependency _myDep;
public GetItemHandler(IDependency dep)
{
_myDep = dep;
}
public Execute(int id)
{
return _myDep.Get(id);
}
}
Note that the way this works is that the Using<T>() method (defined in the BaseController) uses the IoC container to resolve the handler, thus grabbing all it's dependencies. Then we can just use it as normal. I think this pattern really helps to separate out responsibilities and keep your classes and controllers nice and lean.

DI Container and custom-scoped state in legacy system

I believe I understand the basic concepts of DI / IoC containers having written a couple of applications using them and reading a lot of stack overflow answers as well as Mark Seeman's book. There are still some cases that I have trouble with, especially when it comes to integrating DI container to a large existing architecture where DI principle hasn't been really used (think big ball of mud).
I know the ideal scenario is to have a single composition root / object graph per operation but in a legacy system this might not be possible without major refactoring (only the new and some select refactored old parts of the code could have dependencies injected through constructor and the rest of the system using the container as a service locator to interact with the new parts). This effectively means that a stack trace deep within an operation might include several object graphs with calls being made back and forth between new subsystems (single object graph until exiting into an old segment) and traditional subsystems (service locator call at some point to code under DI container).
With the (potentially faulty, I might be overthinking this or be completely wrong in assuming this kind of hybrid architecture is a good idea) assumptions out of the way, here's the actual problem:
Let's say we have a thread pool executing scheduled jobs of various types defined in database (or any external place). Each separate type of scheduled job is implemented as a class inheriting a common base class. When the job is started, it gets fed the information about which targets it should write its log messages to and the configuration it should use. The configuration could probably be handled by just passing the values as method parameters to whatever class needs them but if the job implementation gets larger than say 10-20 classes, it doesn't seem very handy.
Logging is the larger problem. Subsystems the job calls probably also need to write things to the log and usually in examples this is done by just requesting instance of ILog in the constructor. But how does that work in this case when we don't know the details / implementation until runtime? Since:
Due to (non DI container controlled) legacy system segments in the call chain (-> there potentially being multiple separate object graphs), child container cannot be used to inject the custom logger for specific sub-scope
Manual property injection would basically require the complete call chain (including all legacy subsystems) to be updated
A simplified example to help better perceive the problem:
Class JobXImplementation : JobBase {
// through constructor injection
ILoggerFactory _loggerFactory;
JobXExtraLogic _jobXExtras;
public void Run(JobConfig configurationFromDatabase)
{
ILog log = _loggerFactory.Create(configurationFromDatabase.targets);
// if there were no legacy parts in the call chain, I would register log as instance to a child container and Resolve next part of the call chain and everyone requesting ILog would get the correct logging targets
// do stuff
_jobXExtras.DoStuff(configurationFromDatabase, log);
}
}
Class JobXExtraLogic {
public void DoStuff(JobConfig configurationFromDatabase, ILog log) {
// call to legacy sub-system
var old = new OldClass(log, configurationFromDatabase.SomeRandomSetting);
old.DoOldStuff();
}
}
Class OldClass {
public void DoOldStuff() {
// moar stuff
var old = new AnotherOldClass();
old.DoMoreOldStuff();
}
}
Class AnotherOldClass {
public void DoMoreOldStuff() {
// call to a new subsystem
var newSystemEntryPoint = DIContainerAsServiceLocator.Resolve<INewSubsystemEntryPoint>();
newSystemEntryPoint.DoNewStuff();
}
}
Class NewSubsystemEntryPoint : INewSubsystemEntryPoint {
public void DoNewStuff() {
// want to log something...
}
}
I'm sure you get the picture by this point.
Instantiating old classes through DI is a non-starter since many of them use (often multiple) constructors to inject values instead of dependencies and would have to be refactored one by one. The caller basically implicitly controls the lifetime of the object and this is assumed in the implementations (the way they handle internal object state).
What are my options? What other kinds of problems could you possibly see in a situation like this? Is trying to only use constructor injection in this kind of environment even feasible?
Great question. In general, I would say that an IoC container loses a lot of its effectiveness when only a portion of the code is DI-friendly.
Books like Working Effectively with Legacy Code and Dependency Injection in .NET both talk about ways to tease apart objects and classes to make DI viable in code bases like the one you described.
Getting the system under test would be my first priority. I'd pick a functional area to start with, one with few dependencies on other functional areas.
I don't see a problem with moving beyond constructor injection to setter injection where it makes sense, and it might offer you a stepping stone to constructor injection. Adding a property is usually less invasive than changing an object's constructor.

DI: When to list dependencies as params in ctor and when to call Container.Resolve<>()?

I use DI quite a lot in my projects and I'm fairly comfortable with the concept, however there's one aspect which I'm not quite sure about.
So a common use-case for me is to have an ASP.NET MVC Controller where I list the controller's dependencies in the constructor's parameter list, obviously these are passed in when the Controller is constructed by the DI Container, I then assign these to readonly private variables to be later consumed by Actions within the Controller.
Now, my concern is that if I only use an injected dependency (let's say an IMemberRepository) within one Action (and let's say there are 5 other Actions), should I list this as a dependency in the ctor, or should I call Container.Resolve<IMemberRepository>() within the one Action where it's used?
I have to say, I do like listing all my dependencies in the ctor, and I don't particularly like Container.Resolve<>() strewn throughout my code, but, going on the example above, there's no point in getting the DI container to instantiate an IMemberRepository if it's going to be used!
You should never call Container.Resolve from within your application code. This is the Service Locator pattern, and is considered an anti-pattern. Not injecting all dependencies through the constructor means you are hiding the used dependencies, which makes it less clear what depenencies a class has and makes it harder to test that class.
You are concerned about performance when dependencies are injected but not used, but this is normally not an issue, since construction of objects is usually very fast (since all those objects should do during construction is storing all incoming dependencies in private fields). When construction is proven to be too slow for a certaintype, there are other solutions, such as wrapping that dependency into a proxy that lazily initializes that dependency.
If you find that your class gets too many constructor arguments, it is a sign that it has too many responsibilities; it is doing too much. Try to repair this flaw in the class's design instead of falling back to Container.Resolve. For instance, extract a group of dependencies with the classes logic into a single new type and inject that as dependency.
There could be other problems with the design. When your controller depends directly on a repository dependency and you have business logic in the controller, you are missing an abstraction. You are missing a service layer. A good solution is the introduction of command handlers and query handlers.
I second what Steven has said.
If too many constructor arguments bug you then you could also opt for property injection. I favour this approach. There are some objects that, for some or other reason, are not injected into properties if they are not yet fully populated whereas they will be injected into the constructor.
I apply a guard to the dependency on properties to throw an exception if a dependency is null so that I know which dependency it is.
Hope that makes sense.
I would say that it depends on what you are wanting to do with DI.
The approach of using the injected dependencies as parameter in the constructor can end in a very long list of parameters.
This may be necessary for real Test Driven Development where you may want to mock the methods for your injected dependencies.
I personally think that it produces a lot of overhead as the DI Container always has to construct all dependencies, needed in an Action or not.
It is also to be considered that the usage of Actions and PartialViews produce a lot more constructions.
E.g.
public class HomeController : Controller
{
private IMemberRepository _memberRepo = null;
public HomeController(IMemberRepository repo)
{
_memberRepo = repo;
}
public ActionResult Index()
{
MyViewModel viewModel = _memberRepo.DoSomething();
return View(viewModel);
}
[ChildActionOnly]
public PartialViewResult SomePartialAction()
{
return PartialView();
}
}
Where the view Index.cshtml calls the partial view SomePartialAction() by #Html.Action("SomePartialAction").
In this case the constructor of the controller is called twice. Each time for each action. Therefore the DI container is also called twice.
So it really depends. For "hardcore" TDD you have to use the constructor. Otherwise I would resolve the dependencies where and when needed.

ASP.NET MVC IoC usability

How often do you use IoC for controllers/DAL in real projects?
IoC allows to abstract application from concrete implementation with additional layer of interfaces that should be implemented. But how often concrete implementation changes? Should we really have to do job twice adding method to interface then the implementation if implementation hardly will ever be changed? I took part in about 10 asp.net projects and DAL (ORM-like and not) was never rewritten completely.
Watching lots of videos I clearly understand that IoC "is cool" and the really nice way to program, but does it really needed?
Added a bit later:
Yes, IoC allows prepare better testing environment, but we also have nice way to test DAL without IoC. We wrap DAL calls to database into uncommited transactions without risk to make data unstable.
IoC isn't a pattern only for writing modular programs; it also allows for easier testing, by being able to swap in mock objects that implement the same interface as the components they stand in for.
Plus, it actually makes code much easier to maintain down the road.
It's not IOC that allows you to abstract application from concrete implementation with additional layer of interfaces, this is how you should design your application in order to be more modular and reusable. Another important benefit is that once you've designed your application this way it will be much easier to test the different parts in isolation without depending on concrete database access for example.
There's much more about IoC except ability to change implementation:
testing
explicit dependencies - not hidden inside private DataContext
automatic instantiation - you declare in constructor that you need something, and you get it - with all deep nested dependencies resolved
separation of assemblies - take a look at S#arp Architecture to see how IoC allows to avoid referencing NHibernate and other specific assemblies, which otherwise you'll have to reference
management of lifetime - ability to specify per request / singleton / transitive lifetime of objects and change it in one place, instead of in dozens of controllers
ability to do dynamic stuff, like, getting correct data context in model binders, because with IoC you now have metadata about your dependencies; and this shows that maybe IoC does to your object dependencies what reflection does to C# programming - a lot of new possibilities, that you never even thought about
And so on, I'm sure I missed a lot of positive stuff. While the only "bad" thing that I can think about (and that you mentioned) is duplication of interface, which is non-issue with modern IDEs support for refactoring.
Well, if your data interfaces change every day, and you have hundreds of them - you may want to avoid IoC.
But, do you avoid good design practices just because it's harder to follow them? Do you copy and paste code instead of extracting a method/class, just because it takes more time and more code to do so? Do you place business logic in views just because it's harder to create view models and sync them with domain models? If yes, then you can avoid IoC, no problem.
You're arguing that using IOC takes MORE code than not using it. I disagree.
Here is the entire DAL IOC configuration for one of my projects using LinqToSql. The ContextProvider class is simply a thread safe LinqToSql context factory.
container.Register(Component.For<IContextProvider<LSDataContext>, IContextProvider>().LifeStyle.PerWebRequest.ImplementedBy<ContextProvider<LSDataContext>>();
container.Register(Component.For<IContextProvider<WorkSheetDataContext>, IContextProvider>().LifeStyle.PerWebRequest.ImplementedBy<ContextProvider<WorkSheetDataContext>>();
container.Register(Component.For<IContextProvider<OffersReadContext>, IContextProvider>().LifeStyle.PerWebRequest.ImplementedBy<ContextProvider<OffersReadContext>>();
Here is the entire DAL configuration for one of my projects using NHibernate and the repository pattern:
container.Register(Component.For<NHSessionBuilder>().LifeStyle.Singleton);
container.Register(Component.For(typeof(IRepository<>)).ImplementedBy(typeof(NHRepositoryBase<>)));
Here is how I consume the DAL in my BLL (w/ dependency injection):
public class ClientService
{
private readonly IRepository<Client> _Clients;
public ClientService(IRepository<Client> clients)
{
_Clients = clients;
}
public IEnumerable<Client> GetClientsWithGoodCredit()
{
return _Clients.Where(c => c.HasGoodCredit);
}
}
Note that my IRepository<> interface inherits IQueryable<> so this code is very trivial!
Here's how I can test my BLL without connecting to a DB:
public void GetClientsWithGoodCredit_ReturnsClientWithGoodCredit()
{
var clientWithGoodCredit = new Client() {HasGoodCredit = true};
var clientWithBadCredit = new Client() {HasGoodCredit = false};
var clients = new List<Client>() { clientWithGoodCredit, clientWithBadCredit }.ToTestRepository();
var service = new ClientService(clients);
var clientsWithGoodCredit = service.GetClientsWithGoodCredit();
Assert(clientsWithGoodCredit.Count() == 1);
Assert(clientsWithGoodCredit.First() == clientWithGoodCredit);
}
ToTestRepository() is an extension method that returns a fake IRepository<> that uses an in-memory list.
There is no possible way you can argue that this is more complicated than newing up your DAL all over your BLL.
The only way you could have ever written the above test is by connecting to a DB, saving some test clients, and then querying. I guarantee that takes 100+ times longer to execute than this did. (Times that by 1000 tests and you can go get some coffee while you're waiting.)
Also, by using uncommitted transactions for testing you introduce debugging nightmares resulting from ORMs that don't query over uncommitted entities.

Resources