Here's a specific problem that I run into when creating objects, such as collections, that need to be available through the whole scope of the application.
I have the following class:
class UserDataCollection
{
List<UserData> Collection = new List<UserData>();
UserData current;
public UserData Current
{
get { return current; }
set
{
current = value;
}
}
public UserDataCollection( UserData userdata )
{
this.current = userdata;
}
public void Add ( UserData item )
{
Collection.Add(item);
}
}
Now for every UserData object I want to add, it's going to create a new List object each time I go UserDataCollection datacoll = new UserDataCollection(userdata);
So my objects will never be added to the same collection, which is not the point of this collection.
Is this then a good singleton case or just create the object at Application Init and use the same object throughout?
What's the best design practice for something like this?
You could just make the list static. Then there will only ever be one collection.
It depends
If it's a web application, you can create your collection on application start and store it into Application property of HttpContext. If not, you can use a singleton or an IoC container and configure it to always return the same instance of the object.
P.S : If multiple threads of the application will run simultaniously, by sure to use a lock before updating the collection.
Hope it will help.
Collections like this are for multiple objects obviously, so you would instantiate them where you are creating a ... collection of objects... If you want to use a ctor, then it should take as it's parameter a ... collection or enumerable set of those objects...
// Inheriting from List<UserData> eliminates need for most of your code
class UserDataCollection: List<UserData>
{
public UserDataCollection(IEnumerable<UserData> users)
{
foreach (UserData usr in users)
Add(usr);
}
}
If there will only ever be one UserDataCollection per application then I don't see why not make it a singleton.
I like the idea of a Singleton here, if you only want one for your entire application. If you are using this in an ASP.NET application, you will have to watch out with Singletons because static variables are like saving data in Application state...which is probably what you want...but not easily noticeable to the outside world (maintainability issue).
Related
I'm building an intranet using C# webforms. I've got a list object with a bunch of users which I'm cacheing. I'm trying to create a constructor that will do the following when I reference MainADList:
if it exists in the cache and is not null, use it
else generate the list and cache it
I've got the code to do the caching and retrieving, but it isn't encapsulated nicely in a way that I'd like.
public Users MainADList = new Users();
private void GenerateADList()
{
MainADList = (Users) Cache["MainADList"];
if (MainADList == null || MainADList.Count == 0)
{
//generate the list....
Cache["MainADList"] = MainADList;
}
}
Thanks!
You can't create a constructor which does that. A constructor always creates a new object.
Instead, create a static factory method:
public static Users GetUsers()
{
// Consult the cache, and create a new instance if necessary.
}
This may be a singleton - but it certainly doesn't have to be. (I wouldn't artificially impose its singleton-ness unless I really had to. I'm not a big fan of the singleton pattern.)
Alternatively, instead of a static factory method, you could have an instance method in a factory class:
public class UsersFactory
{
// Construct it with a cache, or whatever's required
public Users GetUsers()
{
// Use the cache, or construct a new value.
}
}
Now this is more testable - because you're not relying on any static (global) state. Instead, you can create a new factory from a new cache in each test.
In all of these solutions, you need to consider what threading behaviour you want. If you want to make sure that you only construct the value once, you'll need to use Lazy<T>, static initializer guarantees, or locking.
One general pattern you could follow:
public class ClassName {
public static Object CachedObject {
get {
Object o = (Object)Cache['CacheKey'];
if (o == null)
{
o = GetData();
Cache["CacheKey"] = o;
}
return o;
}
}
}
And treat ClassName.CachedObject as though it's always, eternally, and magically populated.
What you want is known as a Singleton.
Basically what you should do with the code you already have is something like this:
public static GetList
{
get
{
//check if list exists and create it - so basically call your private constructor
//return cached list
}
}
I tried to find a similar question on SO but had no luck. Apologies if it's a duplicate.
What are drawbacks to instantiating class-type variables when they are declared?
In a lot of classes representing Business Object Model we have things like this:
public class RateArea {...}
public class FlatRateSchedule
{
public string ScheduleID {get;set;}
public decimal MaxAmount {get;set;}
}
public class PricingData
{
private List<RateArea> rateAreaList = new List<RateArea>();
private FlatRateSchedule flatRateSchedule = new FlatRateSchedule();
public List<RateArea> RateAreaList
{
get { return rateAreaList; }
set { rateAreaList = value; }
}
public List<FlatRateSchedule> FlatRateScheduleList
{
get { return flatRateScheduleList; }
set { flatRateScheduleList = value; }
}
}
At some point this PricingData class is initialized and some properties are hydrated (but not always all properties).
The thinking being that we're creating "blank" instances of classes so that no properties are ever null. This is convenient because we never have to check if any property is null before accessing it's members. Whether properties are hydrated or not, they would never be "null" to the consuming class. If the properties aren't initialized then code needs to check for null every time before accessing a property.
Is a blanket convention that "all properties of a class should be initialized at all times and never be null" really bad?
Besides using some resources to instantiate and store these "default" class instances, the savings in null-exception-checking code seem to be worth it. Are we missing something?
Not an expert here but
If its a List, it does need to be initialized since you can't add elements if it isn't.
If, throughout the life of your class, your properties may not be always needed you can lazy load them.
You could use .Net 4.0's Lazy<T> class.
From Msdn : "Use an instance of Lazy to defer the creation of a large or resource-intensive object or the execution of a resource-intensive task, particularly when such creation or execution might not occur during the lifetime of the program."
Other than that I think it would be intensive for all your properties to be null and have every consuming class do null checks. Lazy<T> solves this.
I like to initialize values to avoid having to check for null throughout my application. I'd probably go with lazy loading:
public List<RateArea> RateAreaList
{
get {
rateAreaList = rateAreaList ?? new List<RateArea>();
return rateAreaList;
}
set { rateAreaList = value; }
}
As long as your properties are only lists (as in your example), it may be a good convention, making your code more compact and easier to read. Lists can be empty, and if you don't need to distinguish between an empty list and a null reference, this works fine. But if your properties contain other "Business Objects", this may not work so easily. Often the construction of those "child" Business Objects cannot or shall not be done at the time when the "parent" object is constructed.
I have a solution that works, but for educational purposes I want to understand if there is a better/cleaner/right way to do it.
Problem: In my "client" app I have a dictionary Dictionary<String, PremiseObject> where the key (String) is a immutable URL to a resource (it's actually a REST URL). PremiseObject is the base type of a whole set of derived classes; thus the Dictionary actually contains a family of classes all derived from PremiseObject.
A key requirement is I want to try to 'guarantee' that no PremiseObjects get created OUTSIDE of the dictionary.
Solution: I have the following function for getting a object out of the dictionary. It either accesses the existing instance, or if it does not exist creates it:
public PremiseObject GetOrCreateServerObject(string premiseObjectType, string location)
{
PremiseObject po = null;
if (!premiseObjects.TryGetValue(location, out po))
{
string classname;
// Create an instance of the right PremiseObject derived class:
po = // gobbly-gook that is not relevant to this question.
premiseObjects.Add(location, po);
}
else
{
Debug.WriteLine("Already exists: {0}", location);
}
return po;
}
Callers do this:
DoorSensor door =
(DoorSensor)server.GetOrCreateServerObject("DoorSensor",
"http://xyz/FrontDoor");
Works great. But I think there's a pattern or design that would elegantly allow me to encapsulate the "single-instance of each object contained in the dictionary" more.
For example, callers could do this:
DoorSensor door = null;
if (!server.ServerObjects.TryGetValue("DoorSensor",
"http://xyz/FrontDoor",
out door))
Debug.WriteLine("Something went very wrong");
I'm not really what to call this pattern. My ServerObjects are "single-instanced" by location. And my GetOrCreateServerObject is like a factory that lazy creates.
But it's possible for instances to be created that don't get put into the dictionary, which could lead to problems.
Like I said, what I have works... Cheers!
UPDATE 1/26/2011 10:13PM -
I just realized a potential problem: On the server side the object represented by a location/URL can actually be multi-inherited. It is THEORETICALLY possible for an object to be both a DoorSensor and an DigitalRelay.
I currently don't care about any of those cases (e.g. for garage doors I simplified my example above; there really is no DoorSensor I exposed, just a GarageDoorOpener which includes BOTH properties for sensing (e.g. Status) and actuation (e.g. Trigger). But this puts a wrinkle in my whole scheme if I were to care. Since this project is just for me :-) I am going to declare I don't care and document it.
I would propose the following simple idea:
PremiseObject's constructor is declared internal.
A special factory object is responsible for creating (or returning an already created) instances. The dictionary is a part of the factory.
Clients are located in another assembly.
This way PremiseObjects can be created by clients only through the factory. This way you can guarantee that only single instance of object exists for each location.
A variant of the idea would be to declare the PremiseObject's constructor private, and declare the factory a friend; but (unlike C++) C# doesn't have a friend notion.
Ok you can probably avoid a parameter and a cast (in the consumer code any way) with a generic method.
public abstract class PremiseObject
{
protected PremiseObject()
{
}
public string Location { get; set; }
public static void GetSensor<T>(string location, out T sensor)
where T : PremiseObject, new()
{
PremiseObject so;
if(_locationSingltons.TryGetValue(location, out so))
{
sensor = (T) so; // this will throw and exception if the
// wrong type has been created.
return;
}
sensor = new T();
sensor.Location = location;
_locationSingltons.Add(location, sensor);
}
private static Dictionary<string, PremiseObject> _locationSingltons
= new Dictionary<string, PremiseObject>();
}
Then the calling code looks a bit nicer:
DoorSensor frontDoor;
PremiseObject.GetSensor("http://FrontDoor/etc", out frontDoor);
So I like that calling convention - if you want to stay away from throwing an exception you can change the return type to bool and indicate failure that way. Personally I wouls say that an exception is what you want.
You may prefer the call without the out parameter - but if you do that then you have to supply the type to the method call - anyway defining the factory method would look like this:
public static T GetSensor<T>(string location) where T : PremiseObject, new()
{
PremiseObject so;
if (_locationSingltons.TryGetValue(location, out so))
{
return (T)so; // this will throw and exception if the
// wrong type has been created.
}
T result = new T();
result.Location = location;
_locationSingltons.Add(location, result);
return result;
}
Then the calling code looks like this:
var frontDoor2 = PremiseObject.GetSensor<DoorSensor>("http://FrontDoor/etc");
I like both these approaches because nothing has to be repeated. The type of the PremiseObject only gets stated once - there is no need for a string defining the type.
If you want to be really, really sure that no instances of PremiseObject get created that aren't placed in the dictionary, you could make the constructors all private, and create a static constructor (for each subclass) that took as a parameter the Dictionary object you're referring to. This static constructor would check the dictionary object to make sure that there wasn't an existing instance, and then return either the new or the existing instance as required. So something like this:
public class PremiseObject
{
public static Dictionary<string, PremiseObject> PremiseObjects { get; private set; }
static PremiseObject()
{
PremiseObjects = new Dictionary<string, PremiseObject>();
}
}
public class DerivedPremiseObject : PremiseObject
{
private DerivedPremiseObject()
{
}
public static DerivedPremiseObject GetDerivedPremiseObject(string location)
{
DerivedPremiseObject po = null;
if (!PremiseObject.PremiseObjects.TryGetValue(location, out po))
{
po = new DerivedPremiseObject();
PremiseObject.PremiseObjects.Add(location, po);
}
return po;
}
}
And there are a variety of similar strategies you could use. The key is to somehow make the constructor private and only allow access to the constructor through a static method that enforces the logic of the class construction.
Perhaps you could make PremiseObject a singleton, then you wouldn't have to worry about each object in the dictionary beign a single instance?
In the general case, setting access modifiers on your constructors should do the trick of not allowing anyone external to create the objects (barring reflection). However, these would need to be internal, so anything else in the assembly would be able to instantiate them.
I suspect many of your requirements may be met by using an off the shelf dependency injection container that supports singleton instances. It feels close, but maybe not quite the same. (possibly StrutureMap, Ninject, Castle Windsor, or Unity in no particular order)
I'm again in the position to figure a way out to handle lists with subsidiary objects on our business objects.
Actually, our code often looks like this:
public class Object
{
private List<SubsidiaryObject> subsidiaryObjects = null;
public List<SubsidiaryObject> SubsidiaryObjects
{
get
{
if (this.subsidiaryObjects == null)
{
this.subsidiaryObjects = DBClass.LoadListFromDatabase();
}
return this.subsidiaryObjects;
}
set
{
this.subsidiaryObjects = value;
}
}
}
The Con on this:
The property is referenced in presentation layer and used for DataBinding. Releasing the reference to the actual list and replacing it with a new one will end in an referenced list in the GUI that does not have anything left with the list on the object.
The Pro on this:
Easy way of reloading the list (just set the reference to null and then get it again).
I developed another class that uses the following pattern:
public class Object2
{
private readonly List<SubsidiaryObject> subsidiaryObjects = new List<SubsidiaryObject>();
public List<SubsidiaryObject> SubsidiaryObjects
{
get
{
return this.subsidiaryObjects;
}
}
public void ReloadSubsidiaryObjects()
{
this.SubsidiaryObjects.Clear();
this.SubsidiaryObjects.AddRange(DBClass.LoadListFromDatabase());
}
}
Pro on this:
Reference is continous.
The Con on this:
Reloading the list is more difficult, since it just cannot be replaced, but must be cleared/filled with reloaded items.
What is your preferred way, for what situations?
What do you see as Pro/Con for either of these to patterns?
Since this is only a general question, not for a specific problem, every answer is welcome.
Do you need the caller to be able to modify the list? If not you should consider returning IEnumerable<T> or ReadOnlyCollection instead. And even if you do, you will probably be better off making cover versions for Add/Remove so you can intercept modifications. Handing a reference to internal state is not a good idea IMO.
A third option would be to go with option 2, but to create a new instance of the Object2 type each time you need to repopulate the list. Without additional context for the question, that is the option I would select, but there may be reasons why you would want to hold on to the original instance.
I am wondering which one of these would be considered the cleanest or best to use and why.
One of them exposes the a list of passengers, which let the user add and remove etc. The other hides the list and only let the user enumerate them and add using a special method.
Example 1
class Bus
{
public IEnumerable<Person> Passengers { get { return passengers; } }
private List<Passengers> passengers;
public Bus()
{
passengers = new List<Passenger>();
}
public void AddPassenger(Passenger passenger)
{
passengers.Add(passenger);
}
}
var bus = new Bus1();
bus.AddPassenger(new Passenger());
foreach(var passenger in bus.Passengers)
Console.WriteLine(passenger);
Example 2
class Bus
{
public List<Person> Passengers { get; private set; }
public Bus()
{
Passengers = new List<Passenger>();
}
}
var bus = new Bus();
bus.Passengers.Add(new Passenger());
foreach(var passenger in bus.Passengers)
Console.WriteLine(passenger);
The first class I would say is better encapsulated. And in this exact case, that might be the better approach (since you should probably make sure it's space left on the bus, etc.). But I guess there might be cases where the second class may be useful as well? Like if the class doesn't really care what happens to that list as long as it has one. What do you think?
In example one, it is possible to mutate your collection.
Consider the following:
var passengers = (List<Passenger>)bus.Passengers;
// Now I have control of the list!
passengers.Add(...);
passengers.Remove(...);
To fix this, you might consider something like this:
class Bus
{
private List<Passenger> passengers;
// Never expose the original collection
public IEnumerable<Passenger> Passengers
{
get { return passengers.Select(p => p); }
}
// Or expose the original collection as read only
public ReadOnlyCollection<Passenger> ReadOnlyPassengers
{
get { return passengers.AsReadOnly(); }
}
public void AddPassenger(Passenger passenger)
{
passengers.Add(passenger);
}
}
In most cases I would consider example 2 to be acceptable provided that the underlying type was extensible and/or exposed some form of onAdded/onRemoved events so that your internal class can respond to any changes to the collection.
In this case List<T> isn't suitable as there is no way for the class to know if something has been added. Instead you should use a Collection because the Collection<T> class has several virtual members (Insert,Remove,Set,Clear) that can be overridden and event triggers added to notify the wrapping class.
(You do also have to be aware that users of the class can modify the items in the list/collection without the parent class knowing about it, so make sure that you don't rely on the items being unchanged - unless they are immutable obviously - or you can provide onChanged style events if you need to.)
Run your respective examples through FxCop and that should give you a hint about the risks of exposing List<T>
I would say it all comes down to your situation. I would normally go for option 2 as it is the simplest, unless you have a business reason to add tighter controls to it.
Option 2 is the simplest, but that lets other classes to add/remove elements to the collection, which can be dangerous.
I think a good heuristic is to consider what the wrapper methods do. If your AddPassenger (or Remove, or others) method is simply relaying the call to the collection, then I would go for the simpler version. If you have to check the elements before inserting them, then option 1 is basically unavoidable. If you have to keep track of the elements inserted/deleted, you can go either way. With option 2 you have to register events on the collection to get notifications, and with option 1 you have to create wrappers for every operation on the list that you want to use (e.g. if you want Insert as well as Add), so I guess it depends.