I have a class by itself called clientChat that does basic network stuff. I have several other classes linked to different window forms. In my first form I have a variable referenced to the chat class like so:
clientChat cc = new clientChat();
Everything works okay their, the class has been initialized and everything is in motion. After the first forms is done performing it's duty I bring up my second form that's obviously linked to a new class file.
Now my question is, how can I reference what's going on in the clientChat class without setting a new instance of the class? I need to pass data from the form to the networkstream and if I create a new instance of the class wouldn't that require a new connection to the server and basically require everything to start over since it's "new"? I'm a bit confused and any help would be great, thanks. C# on .NET4.0
You could create an instance of clientChat in the beginning of your program and then, simply pass its reference to the classes that need it.
You may want to look into the Singleton design pattern. Mr Skeet has written a good article on how to implement it in C# here. (Just use version 4. its the easiest and works fine =) )
Presumably you would either:
Create the object from the code that creates and shows both forms, and pass a reference to that same instance to both forms, or:
If you create the second form from inside the first form, pass a reference to the instance referenced by the first form to the second somehow (via a property or a constructor, for example).
In additional to #Jens's answer, there are 5 approaches on the linked page, while I think we have the 6th using Lazy<T> in C# 4.0
public sealed class Singleton
{
private Singleton() { }
private static readonly Lazy<Singleton> m_instance = new Lazy<Singleton>(() => new Singleton());
public static Singleton Instance
{
get
{
return m_instance.Value;
}
}
}
Related
I have a fairly simple application that monitors folder activity and logs it on a server.
In this application I start off with a Form object called Form1. On this form I have a NotifyIcon. Because I need to change the text in the BalloonTip of the NotifyIcon from different Forms along the way, I was thinking of setting a static property of Form1 that will point to the only instance of Form1. This is how it would look in my oppinion:
public partial class Form1 : Form
{
private static Form1 staticRef;
// Other private properties
public Form1()
{
InitializeComponent();
staticRef = this;
// Rest of constructor logic
}
public static void changeNotifyBalloonText(String newText, int timeInMillis)
{
if (staticRef != null && staticRef.notifyIcon1 != null)
{
staticRef.notifyIcon1.BalloonTipText = newText;
staticRef.notifyIcon1.ShowBalloonTip(timeInMillis);
}
}
// Rest of public and private methods
}
Other things to be noted:
a. There will never be more than 1 instance of Form1.
b. I always check the value of staticRef against null, before trying to use it.
c. I cannot afford to make a temporary, local instance of Form1 just to set a BalloonTip message.
d. This solution works very well, i'm more interested in knowing if it's "too hacky" and if so - what would be a better approach to my issue?
e. The closest thing I've found that may answer my question (about static properties) to some degree is here:
Is using a static property in a form bad practice knowing that there's only only one instance of the form?
What you have here is a form of the singleton pattern.
The singleton pattern certainly has its detractors and its defenders (google "singleton anti-pattern").
It is though a very convenient way of doing this.
I would recommend an approach like either::
Create a class that represents operations on a notify icon.
Have that class as the only class that accesses staticRef.notifyIcon1.
Have it do so as a reference to notifyIcon1, not as Form1.
Have a static method or property that gets the icon-controlling class.
Or:
Simply have a static method or property that returns the NotifyIcon object.
Make it the only method that accesses the static reference to the form.
The advantage of one over the other is around whether you want to expose the full interface of NotifyIcon or provide a set of operations that make sense to your application.
This way you are still using the singleton pattern, but in restricting the way that it is accessed the fact that there is global state has less of a global impact, relates more directly to the purpose of that global state (the icon itself), and is more readily extended to different uses. e.g. if you some day need to have two icons, you change the method that static method or property to one that does a lookup of some sort, and change all the current calls to use the key for the first icon. Meanwhile, implementation changes up to and including completely changing which form provides that icon can be done quickly in one place.
I think your current design is tightly coupled to other classes sending the notification and it requires your form to be a single instance as well.
You can decouple this a great deal by using an event broker to send the notification to any interested parties. Many frameworks have event brokers, I have used one from Prism but there are others as well.
Your code will then only know about the event broker and what events your class is interested in.
public partial class Form1 : Form
{
private static IEventBroker eventBroker;
// Other private properties
public Form1(IEventBroker eventBroker)
{
InitializeComponent();
this.eventBroker = eventBroker;
this.eventBroker.Register<NotifyBaloonText>(changeNotifyBalloonText);
}
public static void changeNotifyBalloonText(NotifyBaloonText args)
{
notifyIcon1.BalloonTipText = args.NewText;
notifyIcon1.ShowBalloonTip(args.TimeInMillis);
}
// Rest of public and private methods
}
I am developing a Xamarin iOS project, but I suppose this question would apply to any C# project and is not Xamarin specific. I am developing an iPad based kiosk application, where a shop owner logs onto in the morning and then user can signup and order products throughout the day.
When the shop owner logs on in the morning, I make a REST API call which collects the configuration information for that day. For example it will say which products should be featured etc. The API call populates an object called DailySetting.
When a user interacts with the iPad, we go through numerous screens, not always in the same order, each with their own ViewControllers. Each screen sets different properties of a UserInteraction object which is then sent back to the server via a POST request.
My question is where/how do I store the DailySetting and UserInteraction objects? I see it that I have some options:
Store them as a property on the first ViewController in the
higherarchy, then everytime I need to reference the object, loop
through the VC's until I find the root one and then access the public
property. This seems quite wasteful and not very logical.
Make the object's/properties static as there will only be one in use
at any one time. If I understand correctly they could be garbage
collected as they wont be set to anything so probably not the best
approach.
Store the data in a SQLLite database and call that everytime I make
changes. This seems a little over the top to just reference the
current objects.
For the DailySetting object, save it in the application settings, but
is this the best place for temporary settings?
Another and better approach than I can think of...
There must be a correct place that I can attach the objects currently in use and then reference them from different classes/ViewControllers etc.
There are many different ways and philosifies to approach this.
To main concepts are:
a singleton instance of DailySetting or dependancy injection.
Singleton pattern:
public class Singleton
{
private static Singleton instance;
private Singleton() {}
public static Singleton Instance
{
get
{
if (instance == null)
{
instance = new Singleton();
}
return instance;
}
}
}
You call Singleton.Instance everytime you the object.
The other approach is to inject the DailySettings object into every ViewController.
What I do is save an instance in my AppDelegate and pass the AppDelegate itself into every viewcontroller through the constuctor.
Using a dependancy injection system like Structuremap. You can declare instances of objects as singletons then they can be shared between classes.
Registering is simple like this:
For<IYourInterface>().Use<YourClass>().Singleton();
Then in your mvc controller create a constructor that takes in the interface:
public Homecontroller(IYourInterface instance) {
// you now have access to your class here.
// it's declared as a singleton so it can be shared between controllers.
}
I'd recommend structure map because it has a great way of mapping IYourClass to YourClass automagically by recognising the naming convention. This will save you a lot of time as you can omit specifically registering loads of classes to interfaces.
This example shows you how to:
Scan multiple class libraries in an N-Tier architecture.
Use default convention to map interfaces to classes automatically.
Working with MVC controllers.
Register a logger class as a singleton:
public class DefaultRegistry : Registry
{
var lgr = new Logger("filepath or whatever...");
public DefaultRegistry()
{
Scan(
scan =>
{
scan.Assembly("YourApp.Data");
scan.Assembly("YourApp.Domain");
scan.TheCallingAssembly();
scan.WithDefaultConventions();
scan.With(new ControllerConvention());
});
For<ILogger>().Use(lgr).Singleton();
}
}
Structuemap also has great guides to get you started here: http://structuremap.github.io/quickstart/
Note that structuremap doesn't have to be used in MVC. You can use it in any C# application.
I currently have two solutions inside my project.
Solution 1 is the GameEngine
Solution 2 is essentially the front end Adventure
In order to access classes from the GameEngine library a Singleton design approach is used, so for me to access my inventory class for example GameEngine.Instance.Inventory is used.
However, this is adding quite a lot of code now, doing GameEngine.Instance each time, is there a way I can invoke a method or return so I can simply refer to Inventory and it will return the GameEngine.Instance.Inventory class instead? Basically a shortcut.
Thanks In advance :)
One way is to set up a property:
public GameEngine.Inventory Inventory
{
get { return GameEngine.Instance.Inventory; }
}
Now you can use Inventory all over the class to refer to your singleton object. However this will work only within a particular class.
Also, as per #Leri's comment, this migth (and might not) affect performance.
Use a static property:
private static GameEngine.Inventory _inventory;
public static GameEngine.Inventory Inventory
{
get {
if (_inventory == null) {
_inventory = GameEngine.Instance.Inventory;
}
return _inventory;
}
}
You can also add a static method so it will be accessible through the entire project
public static ClsInventory GetInventory()
{
return GameEngine.Instance.Inventory;
}
If your singleton instance is never changed, you can safely use a variable for the instance:
var i = GameEngine.Instance;
then use it with:
i.Inventory
I would like to augment the answers.They all respond properly your question and I upvoted all. However, I would recomend instead of using a singleton, try to change your aproach to injection of dependencies to acces "global" instances.
What would happend when you want to acces other (global) object rather than the inventory? You will have to add another property to your GameEngine. Your engine will become a Frankestain with so many properties belongin to game engine internal instances. This violates the single responsablity pattern.
Besides, when you want to unit test your game, you wil have to setup the ENTIRE GameEngine for each test / fixture. IOD also helps you to decouple your code.
I'm just curious to know that there is the (Name) property, which represents the name of the Form class. This property is used within the namespace to uniquely identify the class that the Form is an instance of and, in the case of Visual Basic, is used to access the default instance of the form.
Now where this Default Instance come from, why can't C# have a equivalent method to this.
Also for example to show a form in C# we do something like this:
// Only method
Form1 frm = new Form1();
frm.Show();
But in VB.Net we have both ways to do it:
' First common method
Form1.Show()
' Second method
Dim frm As New Form1()
frm.Show()
My question comes from this first method. What is this Form1, is it an instance of Form1 or the Form1 class itself? Now as I mentioned above the Form name is the Default instance in VB.Net. But we also know that Form1 is a class defined in Designer so how can the names be same for both the Instance and class name?
If Form1 is a class then there is no (Static\Shared) method named Show().
So where does this method come from?
What difference they have in the generated IL?
And finally why can't C# have an equivalent of this?
This was added back to the language in the version of VB.NET that came with VS2005. By popular demand, VB6 programmers had a hard time with seeing the difference between a type and a reference to an object of that type. Form1 vs frm in your snippet. There's history for that, VB didn't get classes until VB4 while forms go all the way back to VB1. This is otherwise quite crippling to the programmer's mind, understanding that difference is very important to get a shot at writing effective object oriented code. A big part of the reason that C# doesn't have this.
You can get this back in C# as well, albeit that it won't be quite so clean because C# doesn't allow adding properties and methods to the global namespace like VB.NET does. You can add a bit of glue to your form code, like this:
public partial class Form2 : Form {
[ThreadStatic] private static Form2 instance;
public Form2() {
InitializeComponent();
instance = this;
}
public static Form2 Instance {
get {
if (instance == null) {
instance = new Form2();
instance.FormClosed += delegate { instance = null; };
}
return instance;
}
}
}
You can now use Form2.Instance in your code, just like you could use Form2 in VB.NET. The code in the if statement of the property getter should be moved into its own private method to make it efficient, I left it this way for clarity.
Incidentally, the [ThreadStatic] attribute in that snippet is what has made many VB.NET programmers give up threading in utter despair. A problem when the abstraction is leaky. You are really better off not doing this at all.
VB is adding a load of code into your project behind your back, basically.
The easiest way to see what's going on is to build a minimal project and look at it with Reflector. I've just created a new WinForms app with VB and added this class:
Public Class OtherClass
Public Sub Foo()
Form1.Show()
End Sub
End Class
The compiled code for Foo looks like this when decompiled as C#:
public void Foo()
{
MyProject.Forms.Form1.Show();
}
MyProject.Forms is a property in the generated MyProject class, of type MyForms. When you start diving into this you see quite large amounts of generated code in there.
C# could do all of this, of course - but it doesn't typically have a history of doing quite as much behind your back. It builds extra methods and types for things like anonymous types, iterator blocks, lambda expressions etc - but not in quite the same way that VB does here. All the code that C# builds corresponds to source code that you've written - just cleverly transformed.
There are arguments for both approaches, of course. Personally I prefer the C# approach, but that's probably no surprise. I don't see why there should be a way of accessing an instance of a form as if it was a singleton but only for forms... I like the language to work the same way whether I'm using GUI classes or anything else, basically.
I am creating a class library for AutoCAD with .NET.
The problem is that the methods are called one after another from AutoCAD and first one reads input file and creates List of data in memory. However when the new one is called the list is empty.
I need to find a solution how to keep that data.
The List contains data in my created structure. Methods are called independently, but in order.
Short code example:
namespace GeoPjuvis
{
...
public class Program
{
...
//program variables
private List<GeoData> dataList;
private List<DataPoint> points;
private int mapScale;
public Program()
{
dataList = new List<GeoData>();
points = new List<DataPoint>();
}
//Initialization method of the program. Makes praperations. Reads files. Add points to map.
[CommandMethod("geoinit", CommandFlags.Session)]
public void Init()
{
...
}
//method uses data gathered before and selects points
[CommandMethod("selectPoints", CommandFlags.Session)]
public void SelectPoints()
{
...
}...
So why these dataList and points lists are empty when I call SelectPoints() method. And how to avoid that?
I don't know about programming for AutoCAD, but I'd suspect that it's creating a new instance each time. You could try making the variables static (e.g. class-level):
private static List<GeoData> dataList = new List<GeoData>();
Is it instantiating a new class each time it calls a method? (Forgive me, I'm not familiar with coding for AutoCAD.) Try making the class static. If that doesn't work, can you return the value(s) from the first method to AutoCAD and have it send those as arguments to the next method? That wouldn't be the best solution for performance, keep in mind.
Also, for reference, take a look at the a Singleton implementation in C#:
http://msdn.microsoft.com/en-us/library/ff650316.aspx
At a guess, based on the information you've given, does AutoCAD create a new instance of your object for each method call? This would explain why your instance variables are empty.
Try making the variables static and see if the data persists across method calls.
Does the AutoCAD docs have any instructions for writing these programs?
It looks like you are calling a new instance of your class, You could implement a singleton pattern to make sure you are always calling the same instance or persist the points and load them second time round.
Here's a good link for the Singleton implementation in c#, http://csharpindepth.com/Articles/General/Singleton.aspx