First, some background. We have recently taken on a large MVC3 project. The project was pretty much ready to go live some time ago, then the client decided they wanted to re-theme the whole website and add a load more functionality. They employed us to re-theme the site, finish off the remaining functionality and deploy it.
Generally it is built using a very clear, ordered approach, with one repository for each database table and a clear service layer, however there are some oddities that are making me slightly uncomfortable. The main oddity that keeps on nagging at me is that every single repository and service in the application is completely, 100% static (yes, including methods that write to the db). Of course, this doesn't allow for unit testing, however a greater concern is the potential bottlenecks and threading issues that will cause when the application comes under a heavy load. I am already seeing some unexplained delays in processing requests on the stage server, and that is with a trickle of testing traffic.
The application is so huge that rebuilding it to use IOC/instantiated-per-request repositories is pretty much out of the question.
What can I do to avoid potential threading issues upon deployment? Could i use a connection pool and borrow a db connection each time a write needs to happen?
Thanks in advance :)
Edit - here is some of the code that creates an instance of the entity model. Each static method calls this 'DemoEntities' method to obtain an instance of the entity model, which it then uses to execute the db commands. I can see here that, though the method is static, it is actually checking the HttpRequest for a pre-existing instance and creating one if it doesn't already exist. As such, I think we'll be ok.
public static DemoEntities DemoEntities
{
get
{
if (HttpContext.Current != null && HttpContext.Current.Items["DemoEntities"] == null)
{
HttpContext.Current.Items["DemoEntities"] = new DemoEntities();
}
return HttpContext.Current.Items["DemoEntities"] as DemoEntities;
}
set
{
if (HttpContext.Current != null)
HttpContext.Current.Items["DemoEntities"] = value;
}
}
`
Pat
I assume here that your repository classes only contain static methods, not any static state.
The benefit of stateless static classes is that they can be safely turned into regular classes with default parameterless constructors and no concerns over their life-span. It would then be a simple case to extract an interface for testing purposes.
Whenever you need to talk to a repository, simply instantiate one.
Unless the application is doing something with shared state during repository use, you should not need to be concerned about multi-threaded access. The database itself is responsible for handling many concurrent calls.
Currently all bottlenecks and threading issues are potential, sometimes our educated guesses at what could possibly go wrong are themselves wrong - especially so with multi-threading. The slow down might simply be because the database doesn't have the grunt to cope with too many requests.
Related
I'm new to EF and it appears that I have made a mistake with it but I would like clarification.
My scenario:
Winforms App (ClickOnce)
A static class whose only responsibility is to update the DB via a DataServiceContext - single URI
Only one control in the entire application uses this class
With the static class I created a single readonly instance of a DataServiceContext. There is also a GetMethod which gets the data using a ToList() on the context - this list is then used for data binding. I just need simple CRUD so there is a Save/Delete method, entities are passed in and updated.
As I've read a bit more about EF I understand that shared contexts are bad due to issues with concurrency. It seems that I would get away with a static context in this scenario as there would only ever be a single user accessing the same context per application instance or would I? I want to keep things as simple as possible. I'm starting to think perhaps I should turn the static class into a regular class with an immutable DataServiceContext instance shared between methods as a safeguard? Perhaps I should apply a using(DataServiceContext) within each method that makes a service call via SaveChanges to tighten things up even more? Do I need to do these things now or might it be YAGNI?
As I'm self taught here (no mentors), I might be in danger of going AWOL. I probably need some ground rules about EF my current reading as not led me to as yet. Please help.
This isn't just about concurrency (but yes: that is an important concern) - it is also about correctness. If you have a single data-context, there are a few issues:
Firstly, memory: it will slowly grow over the life of the application, as more data is attached into the identity manager and change tracker.
Secondly - freshness: once things are attached to the data-context, you'll see the in-memory object - it may stop showing the up-to-date state of objects in the database
Thirdly - corruption: if anything goes wrong, the noral way of handling that is to simply rollback any in-flight changes, discard the data-context and report the error and/or retry the operation (on a fresh data-context); you can't keep using the old data-context - it is now in an undefined state
For all of these reasons, the general pattern is that you use a data-context only as a unit-of-work, to perform a single operation or a set of related / scoped operations. After that, burn it and start again.
I want to store a small list of a simple object (containing three strings) in my ASP.NET MVC application. The list is loaded from the database and it is updated rarely by editing some values in the site's admin area.
I'm thinking of using HttpContext.Current.Application to store it. This way I can load it in the Global.asax:
protected void Application_Start()
{
RegisterRoutes(RouteTable.Routes);
HttpContext.Current.Application["myObject"] = loadDataFromSql(); // returns my object
}
And then can easily reference it from any controllers or views as needed. Then in the event, the admin area calls the updateMyObject controller action, I can just update the DB and load it in again and replace HttpContext.Current.Application["myObject"].
Are there any cons to doing this? It seems like it will work fine for what I am trying to achieve, however does anyone know of a better way to do this, assuming there is some major disadvantage to the method I've laid out?
What you actually do is Caching, and it's great, since you reduce calls to an external storage (a database or a file, whatever). The trade-off is memory usage, of course. Now, almost any modern web framework, including ASP.NET, includes some kind of a caching mechanism. Either you use it, or you use some kind of a global variable.
Storing data in ASP.NET's built-in Cache object has some significant advantages, since this mechanism actually checks the memory usage and removes the cached data according to some rules.
However, if the data you want to cache is intensively used across the application, and its size is not too large (say, smaller than 1 MB), you may want to store it in as a global variable.
In ASP.NET, global variables are achieved by either using the Application object, like you described in your question, or by writing public static properties/fields in an internal/public class.
Here's my solution to static properties. Note that I use a locking object, to protect the inner data from corruption. It looks like this:
public class WhateverClass
{
private static object theLocker = new object();
private static YourDataType theData;
public static YourDataType TheData
{
get
{
lock (theLocker)
{
return theData;
}
}
set
{
lock (theLocker)
{
theData = value;
}
}
}
}
The usage is very simple:
First time, in Application_Start:
protected void Application_Start()
{
RegisterRoutes(RouteTable.Routes);
WhateverClass.TheData = loadDataFromSql();
}
In any controller:
var myData = WhateverClass.TheData;
This approach is better because you have type safety, since this public static property can be explicitly declared with the exact type. In addition, this kind of storage is more testable since it doesn't depend on the web context.
HTH!
HttpContext.Current.Application is essentially a hangover that is needed for backwards compatibility with classic ASP. It's essentially a static Hashtable with classic ASP locking semantics (Application.Lock / Application.UnLock).
As a weakly-typed Hashtable, you will need to cast objects you retrieve:
MyObject myObject = (MyObject) HttpContext.Current.Application["myObject"];
In an ASP.NET application that is not a migration from classic ASP, I would prefer using other standard .NET stuff, such as:
A static field, using .NET locking semantics if you need locking (e.g. the C# lock keyword, or a ReaderWriterLockSlim instance, depending on your requirements):
static MyObject myObject = LoadFromSql();
The ASP.NET Cache - which has rich functionality for managing expiration, dependencies, ...
Yes, using HttpContext.Current.Application will work fine for what you are doing. No problems.
HttpContext.Current.Application is simply a reference to the static global HttpApplicationState object in .NET for your Web Application, of which there should be one global instance per web application. By storing data there, you provide fast, thread-safe access to your global variables. Be sure to lock them when updating values, as in this example:
System.Web.HttpContext.Current.Application.Lock();
System.Web.HttpContext.Current.Application["WebApplicationPath"] = MyWebApplicationPath;
System.Web.HttpContext.Current.Application.UnLock();
As others have mentioned, you can also create a series of static classes in your App_Code or other folder and there store global static values as well as your HttpContext.Current.Application values, where they can be safely checked for values or updated from the database, or update and check each other, working in tandem. I usually create a static global class to assist in the management and retrieval of the Application variables I store. In this way you have both the state dictionary of the HttpApplicationState class and the web application static objects working together to share and maintain global values. (Keep in mind each static class is assigned per worker process and there may be as many as 10 WP on average by default on many IIS web servers/web applications. So keep data in static types to a minimum.)
Keep in mind as some mentioned server farms do not share Application state. There are many ways to manage this. I'm not a fan of cache because of the ways in which it can expire, fail, become stale, or get corrupted. A simpler solution is to simply use use the database and URL querystrings to communicate across servers and maintain state. Good luck!
If you're deploying to a single web server the approach would work. Consider the Cache object for this as it provides more options for expiration if you need such functionality. (See a comparison, albeit an aged one, here.)
If you're ever going to deploy to a web server farm or equivalent you should use memcached or another web farm friendly caching mechanism. Both the Application and Cache objects only typically exist in a single server context; if your user could be hitting multiple web servers during their session (and the cache needs to be identical) you'll need a shared cache that can be seen from each of the potential web servers.
Regardless of which path you take you will need to invalidate/reload your cache whenever the underlying data changes, which is custom code that varies by app.
This approach works well and can speed things considerably but it's a bit more work than you may realize at first glance...
Application_Start really only gets fired on App Pool Recylce's, IIS Resets or reboots. If your updating these values that infrequently, why not store them in your web.config and access them that way?
That being said, I don't think there is anything wrong with your approach. Though more typically I've seen people using config files for rarely changed values.
Other than testability, what's the big advantage of utilizing D.I. (and I'm not talking about a D.I. framework or IoC) over static classes? Particularly for an application where you know a service won't be swapped out.
In one of our c# application, our team is utilizing Dependency Injection in the web web GUI, the service layer, and the repository layer rather than using static methods. In the past, we'd have POCOs (busines entity objects) that were created, modified, passed around, and saved by static classes.
For example, in the past we might have written:
CreditEntity creditObj = CreditEntityManager.GetCredit(customerId);
Decimal creditScore = CreditEntityManager.CalculateScore(creditObj);
return creditScore;
Now, with D.I., the same code would be:
//not shown, _creditService instantiation/injection in c-tors
CreditEntity creditObj = _creditService.GetCredit(customerId);
Decimal creditScore = _creditService.CalculateScore(creditObj);
return creditScore;
Not much different, but now we have dozens of service classes that have much broader scope, which means we should treat them just as if they were static (i.e. no private member variables unless they are used to define further dependencies). Plus, if any of those methods utilize a resource (database/web service/etc) we find it harder to manage concurrency issues unless we remove the dependency and utilize the old static or using(...) methods.
The question for D.I. might be: is CreditEntityManager in fact the natural place to centralize knowledge about how to find a CreditEntity and where to go to CalculateScore?
I think the theory of D.I. is that a modular application involved in thing X doesn't necessarily know how to hook up with thing Y even though X needs Y.
In your example, you are showing the code flow after the service providers have been located and incorporated in data objects. At that point, sure, with and without D.I. it looks about the same, even potentially exactly the same depending on programming language, style, etc.
The key is how those different services are hooked up together. In D.I., potentially a third party object essentially does configuration management, but after that is done the code should be about the same. The point of D.I. isn't to improve later code but to try and match the modular nature of the problem with the modular nature of the program, in order to avoid having to edit modules and program logic that are logically correct, but are hooking up with the wrong service providers.
It allows you to swap out implementations without cracking open the code. For example, in one of my applications, we created an interface called IDataService that defined methods for querying a data source. For the first few production releases, we used an implementation for Oracle using nHibernate. Later, we wanted to switch to an object database, so we wrote and implementation for db4o, added its assembly to the execution directory and changed a line in the config file. Presto! We were using db4o without having to crack open the code.
This has been discussed exactly 1002 times. Here's one such discussion that I remember (read in order):
http://scruffylookingcatherder.com/archive/2007/08/07/dependency-injection.aspx
http://ayende.com/Blog/archive/2007/08/18/Dependency-Injection-More-than-a-testing-seam.aspx
http://kohari.org/2007/08/15/defending-dependency-injection
http://scruffylookingcatherder.com/archive/2007/08/16/tilting-at-windmills.aspx
http://ayende.com/Blog/archive/2007/08/18/Dependency-Injection-IAmDonQuixote.aspx
http://scruffylookingcatherder.com/archive/2007/08/20/poking-bears.aspx
http://ayende.com/Blog/archive/2007/08/21/Dependency-Injection-Applicability-Benefits-and-Mocking.aspx
About your particular problems, it seems that you're not managing your services lifestyles correctly... for example, if one of your services is stateful (which should be quite rare) it probably has to be transient. I recommend that you create as many SO questions about this as you need to in order to clear all doubts.
There is a Guice video which gives a nice sample case for using D.I. If you are using a lot of 3-rd party services which need to be hooked upto dynamically D.I will be a great help.
I've read several other questions on this topic (here, here, and here), but have yet to see a great answer. I've developed my fair share of data access layers before and personally prefer to use instance classes instead of static classes. However, it is more of a personal preference (I like to test my business objects, and this approach makes mocking out the DAL easier). I have used static classes to access the database before, but I've always felt a little insecure in the appropriateness of such a design (especially in an ASP.NET environment).
Can anyone provide some good pros/cons with regards to these two approaches to developing data access classes with ADO.NET providers (no ORM), in an ASP.NET application in particular. Feel free to chime in if you have some more general static vs. instance class tips as well.
In particular, the issues I'm concerned about are:
Threading & concurrency
Scalability
Performance
Any other unknowns
Thanks!
Static based approaches really typically have one, and only one, main advantage: they're easy to implement.
Instance based approaches win for:
Threading and Concurrency - You don't need any/as much synchronization, so you get better throughput
Scalability - Same issues as above
Perf. - Same issues as above
Testability - This is much easier to test, since mocking out an instance is easy, and testing static classes is troublesome
Static approaches can win on:
Memory - You only have one instance, so lower footprint
Consistency/Sharing - It's easy to keep a single instance consistent with itself.
In general, I feel that instance-based approaches are superior. This becomes more important if you're going to scale up beyond a single server, too, since the static approach will "break" as soon as you start instancing it on multiple machines...
My general feeling is: Why instantiate if you don't have to?
I use static classes when there wont be any use for multiple instances and there isn't a need for instance members. As for the DAL, the point is that there is only one. Why instantiate it if there is no value in it?
Look at this link, which shows that static method calls are faster than instance class method calls.
This link shows that an advantage of using a static class is that the compiler can check to make sure that no instance members are accidentally added.
This link shows that a static class can be used as a convenient container for sets of methods that just operate on input parameters and do not have to get or set any internal instance fields. For a DAL, this is exactly what you have. There is no reason to create any internal instance fields, and therefore, no reason to instantiate.
I have been using a static DAL for years, and I agree with your concerns. Threading and concurrency is the most challenging and in my case I store different connection objects in thread static structures. It has proven to be very scalable and performs well, even more so now that I am converting PropertyInfo into PropertyDescriptor which gives me the same benefits of reflection with better performance. In my DAL I simply have to write:
List<Entity> tableRows = SQL.Read(new SearchCriteria(), new Table());
Everything spawns off the SQL static class, and that makes my code a lot simpler.
For me the main reason is that I don't need to keep the state of that DAL object. The state of the objects it uses don't span the scope of the method they are embeded. This way why would you keep multiple instances of an object, if they are all the same?
With the latest versions of the ADO.NET, seems to be best practice to create and destroy the connection to the database within the scope of your call, and let the ConnectionPool take care of the whole connection reusability issue anyway.
Again with the latest versions of the .NET Framework, TransactionScope (which would be one reason to manage your connections yourself) move up to the business level, which allow you to join multiple calls to the DAL within the same Scope.
So I can't see a compeling case to create and destroy (or cache) instances of the DAL.
We're developing a .NET 3.5 Windows Forms app, using LINQ to SQL and MVP. We have a DataRepository class for retrieving data:
public class DbUserRepository : IUserRepository
{
private IList<UserName> _users;
public IList<UserName> GetUserNames()
{
if (_users == null)
{
// retrieve _users from DB
}
return _users;
}
In order to cache the list of users across all instances of the DBUserRepository, we were going to use the Enterprise Library's Caching Application Block.
But it occured to me, couldn't I just make _users a static member? For some reason that seems like an "old school" way, but it works. Are there any downsides to doing this? Is this considered bad design?
private static IList<UserName> _users;
Thanks
The biggest down-side to doing this is exactly due to what static means; although you can have many DbUserRepository objects, they will always only share one _users variable. Cases where this causes problems:
If your app ever becomes multi-threaded, and you want each thread to have its own distinct user repository (whether or not this is a concern depends on what the repository means in the context of your system)
Unit testing the DbUserRepository class becomes trickier, because if you run multiple unit tests on this class, they will carry state along with them from test to test, meaning that the test-run becomes order dependent... which is pretty undesirable
for simple caching I think static variable is fine, just need to be a bit careful about using locks to protect multiple threads accessing the _users variable. However, a better approach might be using ASP.NET Cache class. I know it is in the System.Web namespace but you can use it outside of ASP.NET application too.
Couple of things to consider.
Thread Safety of initializing the variable
AppDomains. Static variables are local to an AppDomain instance. So if you have multiple AppDomains running you will have multiple instances of the cache
These may or may not be of interest to your application. Likely not, but worth noting.
If you do ever need more than one of them, you'll have to go to extra effort to excise the static one from your code and start passing it around all over the place.