1

To share data (complexe data ) between pages in my windows phone 8 application I want to implement a singleton, but I want it to be generic, is it possible? I suppose that it creates a new instance for each type isn't it?

 public sealed class NavigationContextService<T>
{
    private static readonly NavigationContextService<T> instance = new NavigationContextService<T>();
    private NavigationContextService()
    {
    }
     public static NavigationContextService<T> Instance
    {
        get
        {
            return instance;
        }
    }

    public List<T> ShareList { get; set; }
    public T ShareData { get; set; }
}
Romasz
  • 29,662
  • 13
  • 79
  • 154
Sam
  • 97
  • 10
  • It should work, have you tried it? – Romasz Mar 19 '14 at 13:37
  • Yes it works but I creates for every type a new instance, and a singleton must have only one instance – Sam Mar 19 '14 at 15:21
  • Is there any reason to do such simple things so complex? Put the objects with data in App.cs and access them via App.Current.xxxx – crea7or Mar 19 '14 at 17:41
  • @Samissa I've written an answer in which I tried to explain it a little - maybe it will help you. – Romasz Mar 19 '14 at 20:12

1 Answers1

0

It is creating a new instance for every type, because it is generic - you want it to be like this (if you start with generics, take a look at some tutorials, blogs or MSDN - you will easily find many in the internet).

It is still a singleton. When you use

NavigationContextService<string>.Instance.ShareList.Add("Text");

then you have one Instance for type string. Generics helps a lot when you want to create same methods/classes that differ in type.

On the other hand if you want to create Singleton that will hold different types then you can for example modify your class to be non Generic like this:

public sealed class NavigationContextServiceNonGeneric
{
    private static readonly NavigationContextServiceNonGeneric instance = new NavigationContextServiceNonGeneric();
    private NavigationContextServiceNonGeneric() { ShareList = new List<object>(); }

    public static NavigationContextServiceNonGeneric Instance
    { get { return instance; } }

    public List<object> ShareList { get; set; }
    public object ShareData { get; set; }
}

As you can see in the code above I haven't defined the 'exact' type of shared data - it is object type. Then you can easily hold most of data with it:

NavigationContextServiceNonGeneric.Instance.ShareList.Add("Text");
NavigationContextServiceNonGeneric.Instance.ShareList.Add(3);
NavigationContextServiceNonGeneric.Instance.ShareList.Add(3.0f);

It is singleton, which can hold different types of shared data. BUT it has also disavantages - the main is that you have to remember what type of data you hold and in what order. In my opinion Generic version is better because of that fact.

Everything depends on the purpose of your code. There may be easier and better ways that those two approaches.


As for the Page Navigation, you can for example try to use a method from this article - you extend Navigation service to pass the object:

public static class Extensions
{
  private static object Data;

  public static void Navigate(this NavigationService navigationService, Uri source, object data)
  {
     Data = data;
     navigationService.Navigate(source);
  }

  public static object GetNavigationData(this NavigationService service) { return Data; }
}

Then you use it:

NavigationService.Navigate(yourUri, DataToPass);

After Navigation you can get your data:

string myTextData = NavigationService.GetNavigationData() as string;

This method has to disadvantages: it is not type-safe and your data won't be preserved in Tombstone mode.

As for the second disadvantage you can easily use PhoneApplicationService.State Property for the purpose of Page Navigation - it is a dictionary (which is preserved while tombstoning):

PhoneApplicationService.Current.State.Add("data", yourData);

Then when you want to get your data:

yourDataType yourData = PhoneApplicationService.Current.State["data"] as yourDataType;

There are also more ways in which you can pass the data.

Romasz
  • 29,662
  • 13
  • 79
  • 154
  • My purpose is essentially for transmitting data between pages and to use it like cache to let some data in memory – Sam Mar 20 '14 at 08:26
  • @Samissa I've extended a little my answer about passing the data with navigation. There is some additional information, which may help you. There are many ways how you can pass the data. All methods discussed here should work. – Romasz Mar 20 '14 at 09:20