Silverlight: Where to store data used across pages - c#

I have a Silverlight application that consists of many pages that uses Navigation Framework. What is the ideal place to store data that should be accessed across all pages (XAMLs) and throughout
the lifetime of the application.
EDIT: Forgot to mention that I am currently doing it as a static class

Static members are generally a bad idea. You have no control over lifespan or ability to easily substitute another set of data (and don't get me started on the inability to do proper unit testing). You want to use some type of shared View Model/Data model.
If you are not going the whole PRISM route (we always use PRISM now for Silverlight and WPF), or Unity, or even just MVVM, then use simple singleton accessors on your data object.
There are lots of discussions over the best patterns for C# singletons, but you can learn a lot here http://www.yoda.arachsys.com/csharp/singleton.html
Hope this helps.

I like to create a class called Session, with a static property like this public static Session Default {get {return App.Current.Resources["Session"] as Session;}}, then create a new instance of it in app.xaml like this <classes:Session x:Name="Session"/>, now you can access it in code behind with Session.Default... and you can bind to it with Source binding and it will always be the same instance. I have expanded this pattern to a more complex and flexible pattern with base classes etc but that should suffice for your purposes. I wrote this code in this web window, it might not compile, if you need more help just let me know

Related

UWP MVVM Template10: Access single instance of external API across application

I've been tasked with taking over a partially developed sizeable and complex UWP application using MVVM via Template 10. The app needs to use an in-house developed webservices API and this needs to be used for practically every single function, starting with the initial login page.
So given I need to access a single instance of the API everywhere how do I go about doing that correctly? I've used MVVM a fair bit but never used Template10 and never had to share an instance of an object across an entire MVVM UWP app before.
So far I can think of three ways:
Declare and instantiate API instance in Appl.xaml.cs and use it globally
Create a public Globals class and have the instance as a public static property:
c#
public class Globals
{
private static OurAPI _ourAPI;
public static OurAPI API
{
get { return _ourAPI; }
set { _ourAPI = value; }
}
}
Instantiate the API in the login page and then pass it as a parameter between ViewModels, presumably using the Navigation service.
I'm thinking 1 or 2 are most likely not MVVM compliant and could cause unit testing issues so maybe 3 is the best option? Or is there another, more correct way to do this to adhere to Template10/MVVM concepts and also be able to unit test it?
EDIT: Sorry about the code not formatting, the edit box formats it Ok but when I save it it goes back to one long sentence :-(
The best solution consists of a singleton service and inversion of control (IoC) / Dependency injection . This is a pretty complex topic so I definitely encourage to read about it from several sources.
In summary, you first create an interface for your service, where you declare all the public members and methods. Then you create an implementation of the interface. Then you use a IoC container and register your service as a singleton (single-instance) and then integrate the IoC so that it creates instances of your view models. Then you can put the interface as a constructor parameter of your view model and the IoC container will make sure to provide the singleton instance you registered.
In your case, you are using Template 10 which can be integrated with different IoC containers as seen in the documentation. Check out AutoFac as an example of an IoC container. You can see some examples of registering and resolving a service in the documentation.
For a general solution, check this SO question which demonstrates using AutoFac in UWP.
You can also see some code examples in this SO question and this one specifically for Template 10.
This solution is better than using static and global instances because you never actually deal with any hardcoded reference and actually always work just against the interface. You put the interface as the parameter of your constructor and IoC will take care of providing the instance for you. In addition - you can anytime swap the interface implementation for a different class and you just have to update it in one single location - the IoC registration.

Sharing a Model among pages (views) in a Metro Style App

I have a Metro app consisting of several pages, all deriving from LayoutAwarePage. I've implemented navigation to and back from them. This works like a charm. What I want to do now is to share common data between these views like for example:
access to a model, let's Name it MyModel
an instance of a controller, let's name it MyController
common business logic, let's name it MyLogic
In the past I was used to "inject" those dependencies via constructor. This is now not possible anymore (right?). How can I do this otherwise keeping in mind that I want to avoid:
singletons (because of testing)
public static properties (which is similar to singletons)
Is it ok to pass kind of a context object to the Frame.Navigate() method? Does anybody have a good advice?
P.S. I want to avoid using Frameworks like MVVM light or Cocoon.
Cheerio!
It sounds like you are looking for something very simple. If that is the case, I would just add a property to App.xaml.cs.
You set/get that property from anywhere in your application with something like (App.Current as App).MyProperty. Very brute force but it works.
I have also seen the same approach but with a master container assigned to App.xaml.cs property, then an extension method with a getContainer() method - just to reduce the number of times you have to write (App.Current as App).
Ok, I guess I found a good solution for me [1]. It's still not exactly what I was looking for, because it's using the MVVM light toolkit and its Messenger concept - but it's clean.
[1] http://forums.silverlight.net/p/200771/468507.aspx

Serializing classes created with Singleton pattern

In my program, All of my classes are using singleton pattern, except the one which is the main window. Because of that, all the singleton connections are maintained by one singleton class, "Manager". GUI access methods in other classes via the public methods in this class.
Now, I am trying to save my work (serialize) and I am always getting the error "Form1 not serialized". That is the GUI class. So, I marked that as serialized, knowing that is not a good idea. Now it is saying "System.windows.forms not serialized". Why is this? Is it unable to serialize a class with singleton access? Please help.
Note: I am a Java developer learning "Head First C#". This is my first attempt to make one of their "Lab" problems in my own preferred way.
Without seeing code it's hard to know what is wrong. Principally one can serialize a form (I just did so using the sample Test<T>(T obj) method from MSDN which uses DataContractSerializer).
Having said that... it is unwise to serialize the form itself in order to save the form state. Instead, you should keep your data in a separate class (commonly referred to as a Model class, see MVC) and serialize the data instead. Use data binding or the MVC pattern to connect your form (the view) to the data (the model).
If this is WinForms (as I presume), one can use MVC with WinForms
https://stackoverflow.com/questions/2406/looking-for-a-mvc-sample-for-winforms
For information about data binding with WinForms, see
http://msdn.microsoft.com/en-us/library/ef2xyb33.aspx

Where's the best place to store a commonly-used variable?

What are the best way to store variables in a silverlight application?
Need to transfer store a customer ID throught the application but im not sure what is the best way
Disclaimer: This is a purely subjective answer. Others might object or have better suggestions.
I work mostly in VB.NET and over there, we've got the My.Application namespace where we can keep global variables. VB.NET users also have the option of using a Module for such purposes.
A Module, if I remember right, is equivalent to a static sealed class in C# so you can essentially do something of that sort.
To replicate VB.NET's functionality when I work in C#, I create a static class, with access level set to internal so its members are accessible from within the entire application.
Thus, when I assign a value to a member of the static class, it is accessible from all other classes in the application.
Hope this helps
Store the variable in a place where those things that need to get to it, can; and those things that don't need to get to it, can't. Can't say anything more specific without more information.
If you were following an MVVM pattern then I would have said as a property of the Customer model, with an instance of the customer model being accessed via the ViewModel.
Even if you aren't I would say within the application code and use binding where its needed in the UI. Otherwise you run the risk of changes to your UI causing the loss of customer ID storage at somepoint in the future.
If needed in more than one place then just create a repository that stores all of your data and have that accessed as needed (this way you can decouple your UIs from each other even if they use the same data source.
You may look at using InitParams, without knowing the situation I can't say much more.
http://msdn.microsoft.com/en-us/library/cc838255(VS.95).aspx

Where to maintain common information, that could be accessed by all forms

This is my first winform app in .NET... I have made a couple of ASP.NET app...
In this app, I have some common variables, like current user name, his selected process etc.. etc.. This should be made accessible from all forms in the app at any time... How could I do this... Is there any place like "Session" in ASP.NET here...
Further How do coders generally pass information from one form to another... Here I want to pass on the info I acquired in the first form to the subsequent forms... I use constructor overloading and pass the values as parameters... I'm pretty sure there has to be a better way to do it...
Thanks for your time...
You might want to implement a Singleton object
Implementing the Singleton Pattern in C#
This is typically used for thread safe code, but will also allow you to access the same instance from multiple forms, allowing you to use the same data without having to pass the object around from form to form.
There are quite a number of ways.
Static objects - These are shared accross applications so you can access them from any form or class. This is not advised by many and singleton classes are preferred, but I dont find any problem with these in winform applications.
Public Properties - These are form specific rather than global. Pretty much similar to ASP.NET usage.
Project Settings collection - This can be used to store data that might not change during the application lifecycle. All the forms can access this.
I'd use singleton in this case, checkout this generic singleton implementation.

Categories

Resources