2

Controllers are created per request in Asp.net MVC, this is a fact.

My question is: what is the best practice for for creating common objects (Logger, Localizer, Configurator) that are used in the web application, possible methods from my knowledge are:

  1. Create the object per request then dispose it at the end of the request.
  2. Create the object at the beginning of user session then dispose it at the end of the session.
  3. Create only one object for the entire application and dispose it at application shutdown.
Moha med
  • 89
  • 8

2 Answers2

1

It depends entirely on the scope within these components are used and their dependencies, to elaborate:

Logger

A logger is usually alive throughout the entire lifespan of the application and can be used all over the application (scope), the logger doesn't care for the request or the controller (dependencies). Best Lifetime Scope: Application.

LogSource / LogContext

Unlike logger, LogSource / LogContext are contextual object that are to be used withing a given context (scope), these object are aware of their context (controller / request) (dependencies). Best Lifetime Scope: Controller / Request.

Localizer

Localizer is a bit less clear-cut as the other components. For one it is use application wide (Controllers, Views etc.) (scope). But as for its dependencies the matter is implementation specific, your localizer may need a CultureInfo object for construction or it may not. In a case when it is not required then there are no dependencies for that component and an Application scope will fit.

On the other hand if a culture is required then it is a dependency for that component. Now it's logical to then scope it to a user session but this is where the idea of performance and dependency specifics comes to play. If you scope the localizer to a user session then each user will have x amount of time the server to read the localization file before it's served its response. Additionally the dependency is not the user session but the user's culture, whilst the possible user sessions are infinite, the possible supported locals are all but infinite. Keeping that in mind you can then create a localization pool that contains every supported local (and possibly a fallback local for the ones that aren't supported),scoped to the application, which can serve localizers scoped to user sessions.

To sum up - You can apply the scope-dependencies logic to any component but as we've seed with the localizer it's always best to understand the component and the implication of scoping that component to a specific scope.

Matan Shahar
  • 3,190
  • 2
  • 20
  • 45
1

It really depends on 2 things:

  1. The implementation of those common objects - for example thread safety. For example if your logger has a singleton life-cycle and it has some static property (for example level or a name) then by modifying it in one request it will affect others (and this most probably is unwanted behavior).
  2. The purpose(usage) of those objects - lets assume that you have a LoggerManager or a Configurator or some kind of Factory object that should be initialized only once on application start and then it is used to create(retrieve) other objects (for example an IoC container)then it is certainly makes sense to make it singleton (sometimes it is absolutely required).

From my experience most of the objects have either transient or per-request life cycle. Regarding the singletons (one object for the entire application) - usually it is very clear when to use them. I think a god example is a LoggerManager that is used to create Logger instances based on some static configuration or a Configurator (as you called it) that is initialized on application start and parses some configuration files. My rules of thumb for singletons are:

  • they have to be thread-safe

  • they don't change often

  • they either hold some shared data that is applicable to all threads/requests/users and etc

  • they are heavy objects - if they are light weight you can create a new object each time (transient life-cycle) and most probably you won't notice any difference in performance.

Regarding the session - for me it is more of a cache, so most of the time it holds some user related data

Alex Art.
  • 8,711
  • 3
  • 29
  • 47