There are definitely situations where static is the appropriate solution, as with any application. Any time you have some object that ought to live at the application scope, and not at the request scope, it should be static and you should use static methods to access and manipulate it.
As an example, here's a snippet of code I wrote recently for an ASP.NET application, which is essentially a serializer cache. Serializers are expensive to create and we can reuse the same one per type for as long as our application lives, so there's no need to waste time in each request thread for them:
(Note: this has been stripped down to demonstrate the static aspects)
public class XmlSerializerUtility
{
private static Dictionary<Type, XmlSerializer> serializers = new Dictionary<Type, XmlSerializer>();
private static object sync = new object();
public static T Deserialize<T>(string input)
{
XmlSerializer xs = GetSerializer(typeof(T));
using (StringReader sr = new StringReader(input))
{
return (T)xs.Deserialize(sr);
}
}
public static XmlDocument Serialize(object input)
{
XmlDocument doc = new XmlDocument();
XmlSerializer xs = GetSerializer(input.GetType());
using (MemoryStream stream = new MemoryStream())
{
xs.Serialize(stream, input);
stream.Position = 0;
doc.Load(stream);
}
return doc;
}
private static XmlSerializer GetSerializer(Type type)
{
lock (sync)
{
XmlSerializer xs = null;
if (!serializers.ContainsKey(type))
{
xs = new XmlSerializer(type);
serializers.Add(type, xs);
}
else
{
xs = serializers[type];
}
return xs;
}
}
}