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.
Related
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.
I'm currently having a Class named "SqlData", which contains all the Methods needed to Connect to my MS-SQL Database.
It contains methods for Inserting, Deleting and Updating different kinds of tables - and therefore is used in many Windows of my WPF application.
Let's say that nearly 90% of my WPF-Windows are calling at least three Methods of my SqlData Methods for Loading, Inserting and Updating different records...
At the moment, I need to instantiate my Sql-Class in every Window - therefore I'm thinking of making the entire Class static so I don't need to instantiate it every time?
But also I've read not to use static classes while communicating with external Servers like WebServices or Databases.
Could you give me any advice on how I should go on?
Following a few Methods used in my Class (bool returns true, when the statement completed, otherwise false):
public DataTable GetAllSomething(DataTable _data)
public bool WriteSomething(Object something, out int insertedId)
public bool DeleteSomething(Object something)
Thank you!
At the moment, I need to instantiate my Sql-Class in every Window -
therefore I'm thinking of making the entire Class static so I don't
need to instantiate it every time?
The time taken to instantiate a class in .NET is so ridiculously low that you should not be worried about. Personally I don't use static classes because they introduce strong coupling between the different layers of an application making them more difficult to unit test in isolation.
So I prefer to abstract all database access behind an interface (or abstract class) and then provide an implementation of this interface against a specific database.
Just do not do it, it's ok to create an instance of your class every time it is needed, there is nothing wrong with that.
even if you are not doing it yet right now, you could imagine to use some kind of Dependency Injection soon in the future, or you could write unit tests with any testing framework available in .NET and in general you will have much more options with no static classes.
I always create a database object at the beginning of my app and pass it with the constructors of all windows and classes which need it. It gives me the ability to add data to it, like a connectionstring, which is only needed in the beginning, and there's not a chance methods are being called before the databaseconnection has been set up (as can be with static) because that's done in the constructor.
I'm still in need of help. I have website settings that I want to load using a singleton pattern. There are so many negatives about using this pattern and every one advices to use Inversion of Control or Dependency Injection. I have not yet worked with IoC or DI.
What is the best way to load website settings once and use it across the whole web application? I thought a singleton pattern would be ideal, but I want to go with best practices. Also, does anyone have any sample code regard using IoC or DI loading website settings? Someone even mentioned that I inject the single's Instance method, but what is the use because it's still a singleton? Also, if anyone has some unit tests regaing this loading of website settings with IoC or DI then it would be appreciated.
I am using C#.
Thanks
Brendan
This is a good thread about it : Good case for Singletons?
Other ones:
Singleton: How should it be used
When should you use the singleton
pattern instead of a static
class?
Singletons: good design or a
crutch?
On Design Patterns: When to use the
Singleton?
Singleton is fine in this case if it makes sense to have an instance. Generally it doesn't, and you can just use a static.
Much of the downside of singletons and statics don't exist if they're immutable (those downsides relating to side-effects in global state).
The important thing here is that conceptually, you are looking at the application settings each time you use them. Doing this through a singleton or static just adds a performance boost. If immutability is used to make this impossible to change afterwards, then the only difference between that and looking up the settings each time, is that performance boost.
Conceptually therefore, you aren't introducing global state, you are just improving the performance of global state that already exists. Hence you haven't made things any worse.
Even some who are adamant against global objects (whether singleton or static) make an exception with the flow is one way. Global logging is one-way as the other classes only ever write to it, never read. Global settings are one-way as the other classes only ever read from them, never write.
There are a couple of options, you can use a simple static class :
public class ConfigurationBase
{
public static string Something
{
get { return ConfigurationManager.AppSettings["Something"]; }
}
// ....
}
Or try the Castle Dictionary Adapter :
http://codebetter.com/blogs/benhall/archive/2010/07/22/improving-testability-with-the-castle-dictionary-adapter.aspx
Depending on your needs. It's not necessary to over engineer. Keep it simple and readable first.
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.
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.