I understand that Grails strives very hard to be stateless, however I have a need for one of my controllers to retain a particular fizz value that should be found inside every HTTP request:
class MyController {
List<Fizz> cachedFizzes = new ArrayList<Fizz>()
def index() {
Fizz fizz = extractFizz(params)
cachedFizzes << fizz
...
}
...
}
However when testing this approach locally, it seems that cachedFizzes is re-instantiated with each HTTP request, and so no matter how many times I call one of this controller's actions, the list of Fizzes never grows.
So I ask: how can I (specifically) inject MyController with a List<Fizz> that will exist and grow across the lifetime of the app (not the controller/HTTP request)?
There's rarely a need to create a new controller instance for each request, so it's best to configure them as singletons in Config.groovy:
grails.controllers.defaultScope = 'singleton'
But I think that's the default setting for Grails versions where this is configurable - what version of Grails are you using?
Another option that will work with singleton or instance-per-request controllers is to make cachedFizzes static.
Unrelated - new ArrayList<Fizz>() is way too verbose; just use []. You'll still have the self-documenting collection and generic type on the left and it will function identically.
Related
I was getting a "PooledConnection has already been closed" error when executing a controller with a method that performs a groovy sql query against the dataSource like this
class MyController {
def sessionFactory
def viewWeek (ThingCommand cmd) {
def summary = summaryService()
def db = new Sql(sessionFactory.currentSession.connection())
def sqlStrFind = "SELECT * FROM mytable"
def weekList = db.rows(sqlStrFind)
}
}
In Grails 2 I had seen runtime issues when ordering a Service.method call after inline use of a sessionFactory connection, but not the order above.
This led me to try refactoring the inline code into a new Service. This made the code work, but I noticed that #Transactional was annotating the new Service class, so I guessed that annotating class MyController with #Transactional might do the same for the Controller - and I was correct.
What I don't understand is why #Transactional makes a difference when I thought that Controllers and Services were transactional by default - or did something change in Grails 3?
BTW Burt Beckwith promoted the use of sessionFactory connection as this gave you a pooled connection
#virtualdogbert on slack grails-community provided this answer, which answers my question:
Some where in the Grails 3 line they removed the automatic transaction proxies by default, but you could bring them back with a config change
[see application.yml - grails: spring: transactioManagement: proxies: false ]
The #Transaction(Grails version) was added because it used an AST transform rather than a spring proxy, which in my mind makes it more reliable. Using the AST transform, was promoted over using the proxies for this reason.
The #Transactional AST transform also gives you greater control over how your transactions work.
Even though it's shown in examples I wouldn't use #Transactional in controllers, because it's considered bad practice.
Your​ business logic should be in services - controllers should just be use for routing, and rendering.
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".
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.
I have quite a few things in the constructor of my controller. Is it the case that every time I request a new page with MVC3 then the constructor executes?
A controller instance is required to serve each request. And to obtain this instance (obviously) the controller constructor is called on each request. This being said you should avoid doing many things in this constructor. There are cases for example where for some particular action on this controller you don't need all this initialization and despite this if you put it in the constructor, it will be executed. If the tasks you perform are simply instantiating some other dependencies that your controller needs, then you shouldn't worry about performance, you should worry about properly architecting your application as this job should be handled by a DI framework.
Another common gotcha is that inside the constructor you don't yet have access to the HttpContext and some properties such as Request, Response, ... might not be available in the controller constructor. They become available in the Initialize method.
All this to say that I recommend you avoid putting code (other than storing ctor argument dependencies into private variables for injecting things like services, repositories, ...) in your constructor.
The Controller base class includes the ControllerContext which is a per-request context for a controller which includes references to HttpContext for example.
Let that sink in a moment.
It's very easy to write a custom ControllerBuilder or use the new DependencyResolver to serve up a singleton controller using your favorite DI container. But what that means is your controller may hold onto state from a previous request.
In fact, one of the most common bugs when people use Castle Windsor (which uses Singleton by default I've been told) to create their controllers is they get weird behavior.
As others have pointed out, if your controller is doing a lot of work in the constructor, refactor that work into a dependency on your controller which gets passed in via your controller's contstructor. Let's call that dependency a "service".
That service can itself be a singleton (as long as it doesn't hold onto per-request state) and you can use the DependencyResolver combined with your DI container to instantiate your controllers.
It's up to the ControllerFactory to determine this; the controller factory serves up the controller instance. You could build in the ability to cache the controller, but: it would be better not to pass those references via the ctor of the controller. It would be better to cache each reference separately, and pass to the controller during construction, and let the controller get recreated everytime. If you cache the controller, it will cache other references potentially like HttpContext, which would be not the current request.
HTH.
Yes, M Jacob and this helps us making Data Access request for new DataContext in each request and it is very efficient. it is recommended to initialize a new DataContext (in your controller constructor) in each request rather than making persistent DataContext.
Internet is stateless and the server cannot really distinguish you from any other person out there (technically speaking, ignoring sessions and cookies). You are served the content and connection with you is ended. On your new request the things start from scratch. I agree with you that inability to keep an object alive is an overhead, but even bigger overhead would be if million users made a request with a different requests to the same object. Keeping million copies of the same object is next to impossible.
Regards,
Huske
I have a base Controller ApplicationController that needs to grab the URL Host and do some processing before the child controllers are fired. Since controller constructors are fired before RequestContext is initialized I have to override Initialize method to do my processing.
ApplicationController:
Protected Overrides Sub Initialize(ByVal requestContext As System.Web.Routing.RequestContext)
MyBase.Initialize(requestContext)
Dim host as String
host = Request.Url.Host.ToString
End Sub
What is the logic behind having Controller Constructors fire before the Initialize method?
Also what are the rules to what should be placed in the Initialize Method.
Assuming that constructors are the first instance method ever to be fired in a .NET class, that shouldn't come as a surprise and is not really something MVC specific. It's more how the .NET framework works.
The MVC framework needs to first instantiate a controller and then initialize it => it calls the constructor first. And because performing lots of code that could potentially might throw exceptions, etc... is not always best to be put in a constructor => the presence of the Initialize method. As far as this method is concerned I must admit that I have written lots of ASP.NET MVC code and never had to use it. Action filters always seemed like a better alternative.
So to answer your question:
Also what are the rules to what should be placed in the Initialize Method.
I've never ever put any code and never ever need to override this method. I've always preferred using action filters because this way I am no longer in the obligation of deriving from a common base controller (not that this is a problem).
Sometimes, maybe you would want your request to initialize your variables, so in this case you should use the Initialize method.
For example, if you want to initialize some variables in a different way when the request is local or not, etc.