Click here to Skip to main content
15,886,799 members
Please Sign up or sign in to vote.
2.33/5 (3 votes)
See more:
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
Updated 21-Feb-11 8:57am
v2
Comments
Nish Nishant 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 22-Feb-11 8:52am    
I deleted your fake answers. Never post a fake answer again! Ok?
farhadsoltani 20-Jul-12 10:41am    
dsdflffl

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.
 
Share this answer
 
Comments
Sergey Alexandrovich Kryukov 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
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.

C#
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:

C#
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.
 
Share this answer
 
v2
Comments
elad2109 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?
Nish Nishant 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 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)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900