I'm refactoring a program done in WinForms to WPF and I'm using Caliburn.Micro as a framework to implement the MVVM pattern.
In the old program, I use a StatisHelper class to allow different static variables like the theme, the language, the username or the rights of access, etc ..
I know that it could be insecure because these variables are public, but I doubt that my end users know how to access these values...
Anyway, I would like to know the best practice in MVVM to save global values (in concrete, I'm using Caliburn.Micro framework) that can be accessed for all the view-models.
Thank you for your responses.
You could use a singleton class (frowned upon by some). Note that the constructor is private, so nothing else can create an instance. Use the Instance property to access it. The Instance property in this example will only construct the singleton object the first time it's accessed.
To use it, simply do something like var foo = Globals.Instance.SomeProperty.
Note that this has nothing to do with WPF or MVVM, and could have been used in WinForms as well.
public class Globals {
private Globals _Instance;
public Globals Instance {
get {
if (_Instance == null)
_Instance = new Globals();
return _Instance;
}
}
private Globals() {
}
public string SomeProperty { get; set; }
}
I use a custom StateManager class that implements the Singleton pattern so that there is only one of these instances in the application:
public class StateManager : INotifyPropertyChanged
{
private static StateManager instance = new StateManager();
/// <summary>
/// Initialises a new empty StateManager object.
/// </summary>
public StateManager() { }
/// <summary>
/// Gets the single available instance of the application StateManager object.
/// </summary>
public StateManager Instance
{
get { return instance; }
}
...
}
This is then referenced in my base view model, so that all of my view models have access to it:
public StateManager StateManager
{
get { return stateManager.Instance; }
}
Furthermore, because it is referenced in my view model classes, I can also Bind to the values in XAML:
<Window Title="{Binding StateManager.WindowTitle, Mode=OneWay}" ... />
Well my answer is a combination of ideas from the #Steve and #Sheridan and the link in the comment.
First of all, I have to say separate the data from the code.
As for the data, I would use those Resx files to store all those kinds of resources, whether they are binary resources like simple audio files, images, localizable strings, etc .., because this makes it easy to swap them at run-time.
As for the code, I would use a collection like IConfigurationProvider like this:
public interface IConfigurationProvider {
GetResourceByName<T>(string key); // T is the type of the requested resource
// THIS IS A SIMPLIFIED VERSION, YOU CAN HAVE MORE METHODS
// ACCORDING TO YOUR NEEDS
}
The implementation of this interface could use the Resx files to store and retrieve resources, then you can inject those resources into the different classes that need it.
This haves some advantages like:
Better testability
Can use different media to store the resource data without changing the interface
Swap the implementation at run-time, you can use DI now.
More clear where is the data coming from
Related
I am making a gallery tool that lets you browse and edit objects. I have a 'Library' class that manages the fetching and displaying of the gallery list. I also have an 'ActiveItem' asset that loads all the information of the selected object and deals with modifying it.
Now, there's some information that is stored in the 'library' class (for example the filepath) that I want to use in my activeitem.
I'm a bit confused as to how I can set this up efficiently.
I thought about embedding the activeitem class in the library class, but it gets a bit annoying to have to access all functions and properties of the activeitem through the library class (so instead of writing activeitem.Load() I would have to write lib.activeitem.Load() ). Activeitem already goes 4 levels deep and it's getting a bit much.
Are there other ways of setting this up? Can I store a reference of the library class instance inside the activeitem class, so that the activeitem class can fetch a property of the library instance?
Edit: added some code snippets
This are the class definitions:
class Library
{
...
public string LibDirectory;
...
}
class ActiveAsset
{
...
public SaveAsset()
{
//this method needs to know the LibDirectory property of the libraryclass
}
}
On initiating my winform, I initiate both classes:
Library lib = new Library();
ActiveAsset activeAsset = new ActiveAsset();
Given the concerns in the question comments, if you want ActiveAsset to be able to read information from Library you could change ActiveAsset's constructor to take in Library and store it internally as a private var.
class ActiveAsset
{
private Library _lib
public ActiveAsset(Library lib) {
this._lib = lib
}
public SaveAsset()
{
// reach lib instance from here
this._lib.LibDirectory
//this method needs to know the LibDirectory property of the libraryclass
}
}
If you are worried about design and coupling you could make in interface for Library and then make the constructor use that instead of the Library class
interface ILibrary {
string LibDir { get; set; }
}
class Library : ILibrary {
}
class ActiveAsset
{
private ILibrary _lib
public ActiveAsset(Library lib) {
this._lib = lib
}
public SaveAsset()
{
// reach lib instance from here
this._lib.LibDirectory
//this method needs to know the LibDirectory property of the libraryclass
}
}
As for performance and creating deep levels of nested classes I don't think you will have to worry so much about it, chances are you will hit data save/retrieve performance issues before anything like too many classes. That kind of performance design is only really important when you try to make you code work on small platforms where memory is limited like rasberryPi and such.
I would suggest creating a wrapper class which holds both the Library and the ActiveItem instances. Thus you can have more generalised methods like:
GetAllItems() - gets all items from the library
ActivateItem(Item item) - activates the item provided (stores the given item to a variable in the wrapper class)
etc. Think of that wrapper class as the manager of your application. You would only like to work with that manager regardless of what's beneath it.
New C# devloper and programmer in general. I am hoping to gain insight into the overall proper usage of a Singleton, with insight on properly accessing class items. I cannot seem to figure out how this is done properly.
Background:
I am developing a C# WPF Application, employing MVVM.
The goal of my Singleton is to provide a globally-accessible class, where I am able to update the values inside within my Model.
This Singleton is called out at the top of my ViewModel, using the following syntax:
public CurrentMDL_Singleton currentMDL_Singleton = CurrentMDL_Singleton.Instance;
One of my ViewModels contains the following class:
public class CurrentMDL_Singleton
{
private static CurrentMDL_Singleton instance;
private CurrentMDL_Singleton()
{
CurrentMDL_Constructor currentMDL_Constructor = new CurrentMDL_Constructor();
}
public static CurrentMDL_Singleton Instance
{
get
{
if(instance == null)
{
//Create a new instance
instance = new CurrentMDL_Singleton();
}
return instance;
}
}
}
Knowledge Check:
I intend to use this Singleton to create an instance of "currentMDL_Constructor". currentMDL_Constructor is another class which exists within the same ViewModel, seen below:
public class CurrentMDL_Constructor
{
public Microsoft.Office.Interop.Excel.Application CurrentMDL_Excel { get; set; }
public Microsoft.Office.Interop.Excel.Workbook CurrentMDL_Workbook { get; set; }
public Microsoft.Office.Interop.Excel.Worksheet CurrentMDL_Worksheet { get; set; }
public Microsoft.Office.Interop.Excel.Range CurrentMDL_xlRange { get; set; }
}
Problems:
I am unable to access the currentMDL_Constructor instance, created by the Singleton, as the Singleton constructor is a private member (understandable given the Singleton's purpose).
Within my Model, I am trying to tap into currentMDL_Constructor, to conduct something like the following:
CurrentMDL_Excel = new Microsoft.Office.Interop.Excel.Application();
CurrentMDL_Workbook = CurrentMDL_Excel.Workbooks.Open(MainWindow.MDL_Compare_VM.CurrentMDL_File);
I am unable to access currentMDL_Constructor to begin even thinking about having access to my CurrentMDL_Constructor class.
What is it that I am not understanding? I feel like I am getting lost in the world of instantiation, nested classes and a lack of basic knowledge with Singleton usage, and object orientation in general.
Thank you in advance, and I apologize if this post is redundant (could not find one that helped me).
-Chris
Your code has multiple issues:
First, when writing a singleton that has no dependencies to other classes like in your case, it is best practise to have a static readonly field that holds the single instance, but you should instantiate it straight away like so:
private static CurrentMDL_Singleton instance = new CurrentMDL_Singleton();
This is because, whenever you reference a singleton class, you will probably use its instance. Moving the instantiation to a field init moves it into the type loader and therefore makes it thread-safe. In your code, if clients access the Instance property in parallel, you may end up in a race condition and hence with two different instances of a singleton class, which is something that you would typically want to avoid.
Second, your constructor creates an object and does not save it anywhere, hence you can't access it.
Third, there is absolutely no need to have an instance variable holding a singleton instance, because you can always get it from the static instance field. In your case, it is even dangerous because someone could change it to null and you would not notice.
Lastly, you should really reconsider whether it is really a singleton that you need. A singleton pattern is applied to make sure that there is only one instance of a class, usually not because it is easier to query its contents, because it is a dependency that you cannot easily exchange.
Access the singleton via the public property Instance.
Access the CurrentMDL_Constructor fields as follows:
CurrentMDL_Singleton.Instance.CurrentMDL_Excel
CurrentMDL_Singleton.Instance.CurrentMDL_Workbook
CurrentMDL_Singleton.Instance.CurrentMDL_Worksheet
CurrentMDL_Singleton.Instance.CurrentMDL_xlRange
Thanks to all who helped with this. I was able to figure out where my problems mostly originated from, which was with the layout of the Singleton class.
I want to mention my reasoning for using this Singleton class. I need to ensure only one instance of these Excel variables exists. This is important because my ViewModel and Model depend on referencing instances of the same items. I have been struggling with closing these Excel files because I was mixing up instances. These Excel files are very large, need to remain open in between application functions and close directly after the second function. The Singleton design model solves the problem of ensuing a single instance, and also allows me to access the instance from within my Model very effortlessly.
Knowledge Check : Where I Went Wrong:
My previous understanding was that the private constructor within the Singleton class would set up what I would need to reference after the Singleton was instantiated. This was the wrong thinking.
Don't use the private constructor to instantiate or reference anything; this goes against the main use of the Singleton class. All we're trying to do is make sure only one instance of this Singleton exists; the pivate constructor is there to solely create the Singleton Instance to reference later.
The Fix :
Remove "CurrentMDL_Constructor" class, pull the items that were in that class, which I was trying to create a reference for, into the Singleton main class.
public class CurrentMDL_Singleton
{
public Microsoft.Office.Interop.Excel.Application CurrentMDL_Excel { get; set; }
public Microsoft.Office.Interop.Excel.Workbook CurrentMDL_Workbook { get; set; }
public Microsoft.Office.Interop.Excel.Worksheet CurrentMDL_Worksheet { get; set; }
public Microsoft.Office.Interop.Excel.Range CurrentMDL_xlRange { get; set; }
private static CurrentMDL_Singleton instance = null;
private CurrentMDL_Singleton() {}
public static CurrentMDL_Singleton Instance
{
get
{
if(instance == null)
{
//Create a new instance
instance = new CurrentMDL_Singleton();
}
return instance;
}
}
}
CurrentMDL_Excel, CurrentMDL_Workbook, CurrentMDL_Worksheet, etc. are now all accessible through calling out the instance within the Singleton (thank god). Within my Model, I'm now able to to the following:
> CurrentMDL_Singleton.Instance.CurrentMDL_Excel = new Microsoft.Office.Interop.Excel.Application();
My next step is making this Singleton thread-safe.
Thanks again for the help, and I hope this helps someone else who is trying to understand how to implement Singletons.
-Chris
I'm writing a CAD program. Let's say I have in input class, this class reads various data from a text file and creates lots of lists/dictionaries and .... These data need to be accessed by other methods in other classes to be modified. Now here is how I have done it so far:
I have one static class: Building.cs When I create/or load a project this class holds all the data like list of columns, beams, points, etc. All of these are stored as private fields. I can access these using the class's public methods like GetColumns or GetPoints ...
Now I also have non-static classes. They contain 2-3 public methods. and do some stuff on various parts of the building.
public static class Building
{
private static List<Column> columns;
private static List<Beams> beams;
private static List<Points> points;
public static List<Column> GetColumns()
{
return Columns;
}
}
public class ColumnsService()
{
private List<Columns> columns;
public GroupColumns(List<Columns> columns)
{
this.columns = columns;
}
public void Group()
{
// group columns
}
}
var columns = Building.GetColumns();
var columnsService = new ColumnsService(columns);
columnsService.Group();
I was wondering is this the way to go? How else can I store the data. The data needs to be accessible throughout the lifetime of the program to most of the classes. What are the best practices.
What, semantically, is a Building?
To me, the name implies that it's an instance of a structure. That, in the overall business domain, there can be many "buildings" and at any given moment one is interacting with one of them.
If that's the case, then it seems unintuitive to me to make it static. If there's more than one, it should be an instance model. It would contain attributes which describe it and operations which interact with it. The business domain being modeled should drive the structure of this object before any consideration is given to how other objects are going to interact with it.
So let's assume we make it an instance model:
public class Building
{
// attributes and operations
}
Then, as you ask, how do other objects interact with it?
Depends on the interactions.
Let's say an object needs to "render" a building in some way. Let's call it BuildingPrinter for lack of a better term. Clearly it needs a Building to "print". So it requires one for that operation:
public class BuildingPrinter
{
public void Print(Building building)
{
// implementation
}
}
Or perhaps you have an object which "wraps" a building in some way. Something which can't meaningfully exist without a building, regardless of the operations performed. I can't think of one for that particular business domain, so let's just call it a BuildingWidget. Since it needs a building to exist at all, it requires one:
public class BuildingWidget
{
private Building currentBuilding;
private BuildingWidget() { }
public BuildingWidget(Building building)
{
currentBuilding = building;
}
}
The point is, from the perspective of the models which construct the overall domain, if something is required then it must be supplied. The models shouldn't go out to some global data store, tightly coupling with that data store, to get what they need. This is called the Dependency Inversion Principle.
But where will the consuming code which orchestrates the interactions of these models get instances of a Building? There are a number of potential solutions to that.
Two common patterns would be to have a static factory or a repository. For example:
public class BuildingFactory
{
public static Building FetchBuilding(int buildingId)
{
// implementation
}
}
This factory might have a static cached building object. The building itself isn't static, but for performance reasons an instance of it is cached statically so that it's not constantly re-fetched from a backing data store (such as a database). You might also add methods to invalidate the cache and re-fetch, or encapsulate that logic into the factory itself (such as always re-fetch after 5 minutes or after 10 accesses or some other rule). (Behind the scenes, this factory might even use a repository, shown below, to re-fetch that instance. In which case, you guessed it, a BuildingRepository would be required on the BuildingFactory constructor.)
This factory object may also be responsible for creating a building based on some specifications, if for example you have reason to make the Building constructor private.
Or, to re-fetch from data, consider a repository:
public class BuildingRepository
{
public Building GetBuilding(int buildingId)
{
// fetch from database
}
public Building SaveBuilding(Building building)
{
// save to database, return updated version
}
}
Then other code throughout the domain, including the consuming code, can use these objects to get/save buildings. The factory is static, so that can be invoked anywhere. The repository is instance but doesn't need to be globally distinct, so that can be instantiated anywhere (or pulled form a dependency injection container).
I've been studying the Singleton pattern as it is used in the Settings class. Here's the relevant code from Settings.Designer.cs for my project AccessTest:
internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase
{
private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
public static Settings Default
{
get
{
return defaultInstance;
}
}
public string applicationSetting1
{
get
{
return ((string)(this["applicationSetting1"]));
}
}
}
What is unclear to me is why the property 'applicationSetting1' is accessed through another property 'Default' like this:
var value = AccessTest.Properties.Settings.Default.applicationSetting1;
I'm running VS2013 C# and 4.5.
Because the defaultInstance is static, whereas applicationSetting1 is not. This effectively makes defaultInstance your manager of the class instance. When you call a static method on a class, it doesn't need instantiating,, so you know that you can maintain only a single instance of the class.
Responding to your comments:
Default is NOT the parent of applicationSetting1; Default is simply a global function that returns an instance of applicationSetting1. In the case of a singleton pattern, that always happens to be the same instance.
Manager is my term. To better describe what a singleton pattern is, think of it as a global variable with a single accessor (which I was describing as a manager, simply because it manages the lifecycle of the variable).
Normaly, your Default property is called Instance
So that you can call your singleton like this :
Settings.Instance. X FUNCTION()
Design Pattern by Erich Gamma is pretty solid on design pattern. You should be able to find a PDF on the web easily :)
BTW you should also add this to your Default/Instance property
If(defaultInstance == null)
{
defaultInstance = new Settings();
}
return defaultInstance
That way your singleton is never null and is lazy instantiated
There are a great many posts on the singleton pattern but I couldn't find any that address this particular issue. So I thought I'd take a shot at explaining it myself using this example that I created in my secret laboratory with the help of your posts:
namespace MyProject.Properties
{
internal class Singleton
{
// Create an instance of the class itself.
private static Singleton instance = new Singleton();
// Wrap the instance in a public property.
public static Singleton Instance
{
get {return instance;}
}
// Prevent additional references from being created with a private constructor.
private Singleton() { }
// Create a non-static variable.
public string nonStatic = "non static";
}
}
We know the following about this Singleton class:
The 'Instance' public property can only be accessed statically.
'nonStatic' can't be accessed statically, i.e., it can only be
accessed via a reference.
The private constructor prevents additional
references from being created.
How, then, is it possible to access 'nonStatic' from outside the class?
The framework resolves the dilemma by endowing the static 'Instance' with magical powers that only exist in a singleton situation: 'Instance' becomes a "bridge" that provides access to any non-statics. Ergo, this form works:
var value = MyProject.Properties.Singleton.Instance.nonStatic;
Note: The pattern used my Microsoft in the Settings.Designer.cs file appears to not be a true singleton because the default constructor allows additional references to be created.
I have a WinForms project, which uses a lot of user controls. Some of these user controls use classes from business logic layer. These classes are mainly performing CRUD operation to a database (through data access layer) plus some additional validation and reporting.
The project uses some common objects (logged user, some controllers and validators), which are instantiated in main form and then injected into child user controls via initialization methods or public properties. This means, that I have a lot of code, which just passes these common objects from parent control to child controls.
In order to avoid this, I could create a static class (ApplicationContext for example) and save all common controls into it. This would happen in the main form and all other user controls or forms in the project could use it.
I see that this pattern is discouraged in general (storing some global data in static classes). But what if this data is immutable? Is this approach ever a good idea?
Or do you know any other approach, which could help me get rid of all the initialization code?
You can use an Inversion of Control container like Unity or Autofac and have it automatically wire up your object graph for you.
You can have each object that requires any one of the common objects define a dependency to their interfaces, either though a constructor argument, or as a public property, and the IoC container will wire the appropriate objects together.
Property injection example with Unity:
public class MyUserControl : UserControl
{
[Dependency]
public LoggedUserService UserService { get; set; }
public void Method()
{
// the IoC container will ensure that the UserService
// property has been set to an object
}
}
All you do in the main form is registering the common objects you want the IoC container to know about and then you ask for the root object. The object graph will be assembled magically for you and you don't have to to all the wire code nor care how it is done.
You can use a dependency injection / ioc container for maintaining your global objects.
I have made good experience with the autofac library but there are many other available.
When using setter injection, all of your controls get set dependent objects set automatically.
You'll want to use Singletons for this situation. Singletons will allow you to use the same instance of your object, more safe and flexible than static.
public sealed class Singleton
{
public object Property1 {get;set;}
public void Method1 (){}
static Singleton instance = null;
static readonly object padlock = new object();
Singleton()
{
}
public static Singleton Instance
{
get
{
lock (padlock)
{
if (instance==null)
{
instance = new Singleton();
}
return instance;
}
}
}
}
then you can use it like you would static, but a bit different...
public class Main
{
public Main()
{
Singleton.Instance.Property1 = "somevalue";
Singleton.Instance.Method1();
}
}
You can use a static class to store some immutable data - no problem with this.
How ever if you want to store controls there it might not work as expected.
For example method like OnDataBinding and Render.