I have 3 classes:
MainClass
SettingsClass
FormClass
Now, Mainclass handles most operations and does it's job well, upon being instantiated it creates an instance of SettingsClass, we'll call this instance _settings. SettingsClass holds global settings for the application... like the user name, state of various things, that sort of stuff. During the lifetime of MainClass, a FormClass may or may not be instantiated as well. FormClass needs to be able to access _settings (the same instance of SettingsClass that MainClass uses). At first, I was making the constructor for FormClass take a reference of SettingsClass, which seems to work ok partly. Something like this:
public partial class FormClass : Form
{
private SettingsClass _refSettings;
public FormClass(ref SettingsClass s)
{
_refSettings = s;
}
// The rest of the form stuff here of course
}
And whenever (if ever) FormClass gets created, it would look like this:
public class MainClass
{
private SettingsClass _settings;
private FormClass _form;
public MainClass()
{
_settings = new SettingsClass();
}
// In some function...
{
_form = new FormClass(ref _settings);
_form.Show();
}
}
This seems really weird though, I'm sure there are better ways to make my instance of _settings visible to _form, or I assume so at least. Any ideas
Also, if the way I'm currently doing it is the only/best way, how do I properly dispose of _refSettings when the instance of FormClass goes away Would doing _refSettings = null; actually destroy the object, or would it only destroy the reference itself, thus allowing _settings to be used again and again as many times as FormClass gets instantiated during the lifetime of MainClass
It's getting really confusing to me, not sure how to handle this. In summary, I just want to be able to read/modify an instance SettingsClass from another class that was created in the same scope.
Any help would be appreciated.
Brandon

Question about making object instance visible to other objects
Leho
Cheers
SnakeLair
// Static constructor to initialize the global settings instance
static Settings()
{
try
{
// Attempt to deserialize the previous settings.
_instance = (Settings)the deserialized object;
} catch {
// If deserialization fails, we go ahead and create the empty Settings
_instance = new Settings();
}
}
This would retrieve the old settings whenever the singleton is referenced for the first time I believe, my problem is where to actually serialize it at. I'm not totally sure when a deconstructor would get called with a singleton, since I'm using it "lazily" and never actually explicitly create the instance in my other code.
Thanks Blair, always a help!
Dick Schroth
you need to implement a singleton pattern on Settings:
nb: code just spit out, might have errors
public class Settings
{
// this is the global instance
private static Settings _instance;
private int _timeOutMs;
// Static constructor to initialize the global settings instance
static Settings(){ _settings = new Settings(); }
// Private constructor prevents multiple instancing
public Settings(){}
// Access settings through the static instance
public static Settings Instance
{
get
{
return _instance;
}
}
//A particular setting (Time-Out in Milliseconds)
public uint TimeOutMs
{
get
{
return _timeOutMs;
}
set
{
_timeOutMs = value;
}
}
}
public partial class MyForm: Form
{
public MyForm(){}
protected override OnLoad(EventArgs e)
{
MessageBox.Show(string.format("Timeout (mS): {0}",
Settings.Instance.TimeOutMs.ToString()));
}
}
public class MyFormController
{
private MyForm _form;
public MyFormController()
{
Settings.Instance.TimeOutMs = 2000;
}
public void ShowMyForm()
{
_form = new MyForm();
_form.Show();
}
}
dimondlight
on thing you could do is use the XML editor to create a "settings" typed datatable this would give you the save and load to xml.
Typically the pattern would be
LoadSettings
SaveSettings
LoadDefaults
you would present a user interface showing the current settings. Have a button to load defaults (defined in your xml), restore current, and save settings. Saving would only be done when the UI closes.
Still use the Singleton Pattern to present your typed datatable.
make sense
Mike Lavender
Here is what I've come up with, and it seems to work perfectly so far! Let me know what you think, efficiency-wise, etc!
public class Settings
{
#region Singleton Stuff
private CharacterSettings()
{
}
public static Settings Instance
{
get
{
return NestedSingleton._instance;
}
}
private class NestedSingleton
{
internal static readonly Settings _instance;
static NestedSingleton()
{
try
{
XmlSerializer s = new XmlSerializer(typeof(Settings));
TextReader r = new StreamReader(@"C:\Settings.xml");
_instance = (Settings)s.Deserialize(r);
r.Close();
System.Windows.Forms.MessageBox.Show("Settings loaded.");
}
catch
{
_instance = new Settings();
System.Windows.Forms.MessageBox.Show("Settings created.");
}
}
}
#endregion
#region Methods
public void Serialize()
{
XmlSerializer s = new XmlSerializer( typeof(Settings));
TextWriter w = new StreamWriter(@"C:\Settings.xml");
s.Serialize(w, Settings.Instance);
w.Close();
}
#endregion
}
In my main application, in my equivalent to the OnClosing method of a form (again, I'm communicating with a COM client, whos interface has a specific method that is called right before the main application closes). I simply do:
Settings.Instance.Serialize();
When I run the application for the first time, I successfully receive the "Settings created." message box, when I close the application I successfully receive the "Settings saved." box, and when I re-run it, I get the "Settings loaded." box and the settings are indeed the same. So it appears to be working! I did change singleton pattern's design around a bit, based on the article here: http://www.yoda.arachsys.com/csharp/singleton.html
Does this look efficient
caeriel
"Are you down with OOP "
get these books:
Design Patterns: Elements of Reusable Object-Oriented Software
Refactoring: Improving the Design of Existing Code
cheers!