Click here to Skip to main content
Rate this: bad
good
Please Sign up or sign in to vote.
See more: C# Design Patterns
Hello everyone,
 
I would appreciate help with a design question:
I have a singleton instance.
 
I'm thinking of adding a member to it: an array of instances (of class x) where x is a class with constructor that gets some parameters.
 
I want each cell in the array to have lazy initialization.
 
I need each object to be singleton - but is there any reduction or simple way to achieve the same without the pattern the whole array is a member of a singleton already?
 
What design pattern would you recommend to me when:
1) Access to the array's objects need to be thread safe
2) No need to be type safe
 
Thanks in advance to any idea\suggestion
Posted 21-Feb-11 8:16am
Edited 21-Feb-11 8:57am
jim lahey24.9K
v2
Comments
Nishant Sivakumar at 21-Feb-11 17:25pm
   
I have updated my answer in response to your comment.
 
In general you should post a comment to discuss the thread. You should not post an answer to give feedback to an answer. Thanks.
Toli Cuturicu at 22-Feb-11 8:52am
   
I deleted your fake answers. Never post a fake answer again! Ok?
farhadsoltani at 20-Jul-12 10:41am
   
dsdflffl
Rate this: bad
good
Please Sign up or sign in to vote.

Solution 1

I would assume that because the new members you propose to add are members of a singleton object, that they will in fact also be singletons by means of association. in a traditional singleton pattern you access the only instance via the static .Instance member which can have a double locking patter around it:
 
http://msdn.microsoft.com/en-us/library/ff650316.aspx[^]
 
have a look at the section "Multithreaded Singleton".
 
hope it helps.
  Permalink  
Comments
SAKryukov at 26-Feb-11 12:39pm
   
Good answer, my 5.
I also write a bit in support of your idea in your deleted Answer here: http://www.codeproject.com/Answers/162529/Is-it-necessary-to-create-class-in-vb-net.aspx
 
Did you delete your post yourself? Perhaps to avoid flames?
--SA
Rate this: bad
good
Please Sign up or sign in to vote.

Solution 3

Okay, something like this may be what you are after. In my example, I've assumed that ClassX is the type of each cell, and it's this class that you want to lazy-initialize. By the way ClassX is not a singleton by definition, since you want to have multiple instances of that class. When you load up the main singleton class, call AddCell for every cell that you want to initialize. The underlying ClassX instance will not be created but we store the required arguments. Later, you can call GetCell to get each cell (ClassX instance) and it will be created on demand. So those indices that you do not access will not have their cells initialized. You can improve the interface by adding an indexer that will call GetCell (so it's smoother to access the cells) but that's up to you. Let me know if you have any questions.
 
public class ClassX
{
  public ClassX(int x, int y)
  {
      // some heavy initialization here
  }
}
 
public sealed class SingletonClass
{
  private class InnerClass
  {
      static InnerClass()
      {
      }
 
      public static readonly SingletonClass instance =
        new SingletonClass();
  }
 
  private SingletonClass() { }
 
  public static SingletonClass Instance
  {
      get
      {
          return InnerClass.instance;
      }
  }
 
  const int CellCount = 100;
 
  private ClassX[] cells = new ClassX[CellCount];
 
  private Dictionary<int, Tuple<int, int>> paramsMap =
    new Dictionary<int, Tuple<int, int>>();
 
  public void AddCell(int index, int x, int y)
  {
      // Todo: Add error check for the index (should be valid for the array)
      paramsMap[index] = Tuple.Create(x, y);
  }
 
  public ClassX GetCell(int index)
  {
      if (cells[index] == null)
      {
          if (paramsMap.ContainsKey(index))
          {
              // The cell is lazy constructed (on demand)
              cells[index] = new ClassX(
                paramsMap[index].Item1, paramsMap[index].Item2);
          }
          else
          {
              throw new InvalidOperationException();
          }
      }
 
      return cells[index];
  }
}
 
[Edit]
~~~~~~~~
 
If you want the GetCell code to be thread-safe, you can change it to:
 
public ClassX GetCell(int index)
{
  lock (cells)
  {
      if (cells[index] == null)
      {
          if (paramsMap.ContainsKey(index))
          {
              // The cell is lazy constructed (on demand)
              cells[index] = new ClassX(
                paramsMap[index].Item1, paramsMap[index].Item2);
          }
          else
          {
              throw new InvalidOperationException();
          }
      }
 
      return cells[index];
  }
}
 
And what I meant by saying that ClassX cannot be a singleton in this scenario is that you have multiple instances of it. Perhaps you mean to say that it's a virtual-singleton for every unique set of arguments that you pass to that. If that's the case, you'd have to write code to implement that check because my code will not prevent them from adding two or more ClassX instances with the same parameters. I hope that makes sense.
  Permalink  
v2
Comments
elad2109 at 21-Feb-11 17:30pm
   
10x.
 
Regarding the "lock"
my q: is it realy needed? because the singleton is thread safe. no?
Or just its creation is thread safe?
Nishant Sivakumar at 21-Feb-11 17:32pm
   
The singleton access is thread safe, but multiple threads can hold references to this same singleton. So you still need to make sure that calls that write to the object state are synchronized.
elad2109 at 21-Feb-11 17:45pm
   
10x

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

  Print Answers RSS
0 Sergey Alexandrovich Kryukov 886
1 OriginalGriff 390
2 CPallini 255
3 Volynsky Alex 205
4 Richard Deeming 175
0 OriginalGriff 5,540
1 Sergey Alexandrovich Kryukov 4,668
2 CPallini 4,540
3 George Jonsson 3,102
4 Gihan Liyanage 2,445


Advertise | Privacy | Mobile
Web02 | 2.8.140916.1 | Last Updated 21 Feb 2011
Copyright © CodeProject, 1999-2014
All Rights Reserved. Terms of Service
Layout: fixed | fluid

CodeProject, 503-250 Ferrand Drive Toronto Ontario, M3C 3G8 Canada +1 416-849-8900 x 100