Objects creation lifetime in Asp.net MVC5 - asp.net

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:
Create the object per request then dispose it at the end of the request.
Create the object at the beginning of user session then dispose it at the end of the session.
Create only one object for the entire application and dispose it at application shutdown.

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.

It really depends on 2 things:
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).
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

Related

How to introduce application-wide context object?

I need to make several properties accessible from application's business layer. Those are some ids and common settings. Most of them are valid only through request-response lifespan.
This is a web application (ASP.NET Web Forms to be specific) with dependency injection set up.
Currently those properties are passed through method parameters directly to business layer's services. That works but is not very efficient since:
sometimes parameters' values need to be passed deeper obscuring the readability a bit
some properties should be lazy resolved, and this should be done only once per request
retrieving properties which are resolved by touching a database can be confusing for new developers (there is not unified way of doing this)
some services are constructed by a factory which enriches them with some config parameters
I was thinking about introducing an application context interface, with an implementation in the main project, which would be created on every request. It could be injected to the services directly making them parametrized automatically and independently (services won't need the factory anymore).
Is it how this problem should be tackled or maybe there are some other options?
One option I don't like here is that it might bond the main particle with business layer which is not a perfect example of The Clean Architecture.
Id say you solution is a very common one - inject an 'application context' into your classes. One thing I would be careful of though is making sure you are following the Integration Segregation Principle (from SOLID). Dont just start making all your classes expect an application context instance. Instead, design interfaces that split the application context up, and have your classes expect them as dependencies. Your application context will then need to implement all the interfaces.
This is the correct way to do things as it decouples your classes from implementation. Really your classes don't care if their dependency is from one giant application context, they just care about specific methods implemented by it. This will make your code more robust as you will reduce the risk of breaking something if you change the implementation of the application context later on.
Why don't you use some dependency injection container? Your global settings and parameters can be registered to it as pseudo-singletons and then you will be able to neatly request them from any point inside your application.

Is the following request-scoped injection thread-safe?

#WebListener
public class AllRequestsWebListener implements ServletRequestListener {
#Inject HttpRequestProducer producer;
public void requestInitialized(ServletRequestEvent sre) {
producer.requestInitialized(sre);
}
}
...
#RequestScoped
public class HttpRequestProducer {
...
}
I don't know howto inject request-bean as method-parameter and therefore I can guess that it will work properly when Request-bean injection is threadLocal. Can someone explain me how it's implemented in a thread-safe manner?
What you have injected in your bean is a proxy representing the real deal. The proxy will always forward the invocation to the correct bean
Intuition based answer
I believe it is thread safe, as request scope is thread safe (session and above are not, as a user can open multiple browser sessions and use the same session ID)
I tested it, although it's empiric evidence, but the injected HttpRequestProducer gets a new instance each request.
Note that the requestInitialized and requestDestroyed can be (and in practice are) different threads, so I will investigate further if you intend to use the same injected object on both methods.
Specs backed answer
The hard part was to find hard evidence for this claim in the specs.
I looked into the CDI spec and couldn't quickly find conclusive evidence that a #RequestScoped object is thread safe (e.g. using thread local) however I assume that a #RequestScoped bean is using the same scope as the scoped beans in Java EE 5: (see here)
In there this clause is interesting:
Controlling Concurrent Access to Shared Resources In a multithreaded
server, it is possible for shared resources to be accessed
concurrently. In addition to scope object attributes, shared resources
include in-memory data (such as instance or class variables) and
external objects such as files, database connections, and network
connections.
Concurrent access can arise in several situations:
Multiple web components accessing objects stored in the web context.
Multiple web components accessing objects stored in a session.
Multiple threads within a web component accessing instance variables.
A web container will typically create a thread to handle each request.
If you want to ensure that a servlet instance handles only one request
at a time, a servlet can implement the SingleThreadModel interface. If
a servlet implements this interface, you are guaranteed that no two
threads will execute concurrently in the servlet’s service method. A
web container can implement this guarantee by synchronizing access to
a single instance of the servlet, or by maintaining a pool of web
component instances and dispatching each new request to a free
instance. This interface does not prevent synchronization problems
that result from web components accessing shared resources such as
static class variables or external objects. In addition, the Servlet
2.4 specification deprecates the SingleThreadModel interface.
So in theory, it seems that the object itself is going to have one instance per request thread, however I couldn't find any hard evidence that this is supported.

Why spring mvc scope variables require serialization?

Recently we faced the issue of flowscope values not being set across the flow, but later after the investigation found that all the flowscope variables should be serialized ( my mistake i did not read the line from the spring webflow documentation - the line "any objects stored in flow scope need to be Serializable"
I feel this is kind of session information, in general we don't serialize session variable. Just curious why this serialization required for this spring webflow ?
By forcing flow scoped objects to be Serializable, it provides the flexibility to safely store them anywhere - a database, on disk, etc - and then re-store them when returning to whatever flow state you were in. While your particular server/environment might be a single machine, with every HttpSession (the default "backing" for spring web flow state) persisted in memory, others might have clustered/distributed web/app servers.

Custom IIdentity or IPrincipal Or something else

I'm finding that in the current application I'm working with, I'm retrieving several entities (related to the authenticated users account) in almost every controller. These entities are cached at the orm layer however, it seems that these entities would be a good candidate to load once at authentication time and add a few properties to the applications custom IPrincipal object.
Another option I was thinking of was creating a custom context object (with the users related account objects) and passing it around with the current request.
Benefits / drawbacks to either approach? Is there another way of dealing with commonly used objects like this?
It sounds like you miss the fact that the instance of IPrincipal/IIdentity is recreated upon every request. It is not persisted anywhere if you not persist it in an explicit way.
I don't think then there's performance difference between a custom principal class holding the data vs a cached ambient property.
On the other hand, the drawback of a custom authentication classes is that you have to provide a custom authentication module so that these instances are recreated during AuthenticateRequest event in the processing pipeline. In other words, you'd have to replace FormsAuthenticationModule with your own one. This is not difficult but I wouldn't do this if it is not absolutely necessary.
Note also that some data can be persisted in the UserData section of the forms cookie. This means that you can have it as long as the cookie is valid and create it only once.

Removing singletons from large .NET codebase

The context:
(Note: in the following I am using "project" to refer to a collection of software deliverables, intended for a single customer or a specific market. I am not referring to "project" as it is used in Visual Studio to refer to a configuration that builds a single EXE or DLL, within a solution.)
We have a sizable system that consists of three layers:
A layer containing code that is shared across projects
A layer containing code that is shared across different applications within a project
A layer containing code that is specific to a particular application or website within a project.
The first two layers are built into DLL assemblies. The top layer is an assortment of EXEs and/or .aspx web applications.
IIRC, we have a number of different projects that use this pattern. All four share layer 1 (though often in slightly different versions, as managed by the VCS). Each of them has its own layer 2. Each of them has its own set of deliverables, which can range from a website, or a website and a background service, to our largest and most complex (and the bread-and-butter of our business) which consists of something like five independent web applications, 20+ console applications/background services, three or four independent web services, half-a-dozen desktop GUI apps, etc.
It's been our intent to push as much code into levels 1 and 2 as possible, to avoid duplicating logic in the top layers. We've pretty much accomplished that.
Each of layers 1 and 2 produce three deliverables, a DLL containing the code that is not web-related, a DLL containing the code that is web-related, and a DLL containing unit tests.
The problem:
The lower levels were written to make extensive use of singletons.
The non-web DLL in layer 1 contains classes to handle INI files, logging, a custom-built obect-relational mapper, which handles database connections, etc. All of these used singletons.
And when we started building things on the web, all of those singletons became a problem. Different users would hit the website, log in, and start doing different things. They'd do something that generated a query, which would result in a call into the singleton ORM to get a new database connection, which would access the singleton configuration object to get the connection string, and then the connection would be asked to perform a query. And in the query the connection would access the singleton logger to log the SQL statement that was generated, and the logger would access the singleton configuration object to get the current username, so as to include it in the log, and if someone else had logged in in the meantime that singleton configuration object would have a different current user. It was a mess.
So what what we did, when we started writing web applications using this code base was to create a singleton factory class, that was itself a singleton. Every one of the other singletons had a public static instance() method that had been calling a private constructor. Instead, the public static instance() method obtained a reference to the singleton factory object, then called a method on that to get a reference to the single instance of the class in question.
In other words, instead of having a dozen classes that each maintained its own private static reference, we now had a single class that maintained a single static reference, and the object that it maintained a reference to contained a dozen references to the other, formerly singleton classes.
Now we had only one singleton to deal with. And in its public static instance() method, we added some web-specific logic. If we had an HTTPContext and that context had an instance of the factory in its session, we'd return the instance from the session. If we had an HTTPContext, and it didn't have a factory in its session, we'd construct a new factory and store it in the session, and then return it. If we had no HTTPContext, we'd just construct a new factory and return it.
The code for this was placed in classes we derived from Page, WebControl, and MasterPage, and then we used our classes in our higher-level code.
This worked fine, for .aspx web applications, where users logged in and maintained session. It worked fine for .asmx web services running within those web applications. But it has real limits.
In particular, it won't work in situations where there is no session. We're feeling pressure to provide websites that serve a larger user base - that might have tens or hundreds of thousands of users hitting them dynamically. Up to now our users have been pretty typical desktop business users. They log into our websites, and stay in them much of the day, using our web apps as an alternative to a desktop app. A given customer might have as many as six users who might use our websites, and while we have a thousand or more customers, combined they don't make for all that heavy a load. But our current architecture will not scale to that.
We're also running into situations where ASP.NET MVC would be a better fit for building the web UI than .aspx web forms. And we're exploring building mobile apps that would be communicating with stand-alone WFC web services. And while in both of these, it looks like it's possible to run them in an environment that has a session, it looks to limit their flexibility and performance fairly severely.
So, we're really looking at ways to eliminate these singletons.
What I'd really like:
I'm trying to envision a series of refactors, that would eventually lead to a better-structured, more flexible architecture. I could easily see the advantages of an IoC framework, in our situation.
But here's the thing - from what I've seen of IoC frameworks, they need their dependencies provided to them externally via constructor parameters. My logger class, for example, needs an instance of my config class, from which to obtain the current user. Currently, it is using the public static instance() method on the config class to obtain it. To use an IoC framework, I'd need to pass it as a constructor.
In other words, from where I sit, the first, and unavoidable task, is to change every class that uses any of these singletons so as to take the singleton factory as a constructor parameter. And that's a huge amount of work.
As an example, I just spent the afternoon doing exactly that, in the level 1 libraries, to see just how much work it is. I ended up changing over 1300 lines of code. The level 2 libraries will be worse.
So, are there any alternatives?
Typically, you should try to wrap the contextual information into its own instance and provide a static accessor method to refer to it. For example, consider HttpContext and its available every where in web application via HttpContext.Current.
You should try to devise something similar so that instead of returning singleton instance, you would return the instance from the current context. That way, you need to not change your consumer code that refers to these static methods (e.g. Logger.Instance()).
I generally roll-up information such as logger, current user, configuration, security permissions into application context (can be more than one class if need arises). The AppContext.Current static method returns the current context. The method implementation goes something like
public interface IContextStorage
{
// Gets the stored context
AppContext Get();
// Stores the context, context can be null
void Set(AppContext context);
}
public class AppContext
{
private static IContextStorage _storageProvider, _defaultStorageProvider;
public static AppContext Current
{
get
{
var value = _storageProvider.Get();
// If context is not available in storage then lookup
// using default provider for worker (threadpool) therads.
if (null == value && _storageProvider != _defaultStorageProvider
&& Thread.CurrentThread.IsThreadPoolThread)
{
value = _defaultStorageProvider.Get();
}
return value;
}
}
...
}
IContextStorage implementations are application specific. The static variables _storageProvider gets injected at the application start-up time while _defaultStorageProvider is a simple implementation that looks into current call context.
App Context creation happens in multiple stages - for example, a global information such as configuration gets read and cached at application start-up while specific information such as user & security gets formed at authentication stage. Once all info is available, the actual instance is created and stored into the app specific storage location. For example, desktop application will use a singleton instance while web application can probably store the instance into the session state. For web application, you may have logic at start of each request to ensure that the context is initialized.
For a scalable web applications, you can have a storage provider that will store the context instance into the cache and if not present in the cache then re-built it.
I'd recommend starting by implementing "Poor Man's DI" pattern. This is where you define two constructors in your classes, one that accepts an instance of the dependencies (IoC), and another default constructor that new's them up (or calls a singleton).
This way you can introduce IoC incrementally, and still have everything else work using the default constructors. Eventually when you have IoC being used in most places you can start to remove the default constructors (and the singletons).
public class Foo {
public Foo(ILogger log, IConfig config) {
_logger = log;
_config = config;
}
public Foo() : this(Logger.Instance(), Config.Instance()) {}
}

Resources