tags:

views:

113

answers:

5

As mentioned in a previous post, I am currently learning C#, and for my first (well second if you include hello world and some messing about) real project, I'm going to create a basic EPOS system and then expand upon it..

My intention is to have all pricing, Cashier details, sales transactions, etc.. stored within a MySQL Database (I can move from PHP to C#, but I can't bring myself to moving away from MySQL!)

What I would like to check is the following:

I have 2 forms(at present)

  • A login screen (where the user enters their PIN number)
  • The main Sales screen.

When the user logs in, I am going to authenticate them against the details held within my database, and if successful, then I will load the main sales screen.

I need to somehow transfer information around between forms, so what I have done is created a new class file called variableStore.cs in here, I am going to be storing the userID, userName (so I can have "Currently Logged in: John Doe" on each form status bar.

But I will also be using the same file for transferring "transaction total", etc.. around between forms.

Is this the correct (ok, not correct, but is this how you would do it?) way of doing things?

+1  A: 

No, that is not how I would handle things.

A much better way of handling is passing the values between forms either through the constructor, properties, or methods.

Constructor

public class SalesForm : Form
{
    public SalesForm(string userName)
    {
        Text = "Currently Logged In: " + userName;
    }
}

Now, on the Login Form button click handler (after authenticating the user):

var mainForm = new SalesForm(userName);
mainForm.Show();

Property

public class SalesForm : Form
{
    private string _userName = null;

    public string UserName 
    { 
        get
        {
            return _userName;
        }
        set
        {
            _userName = value;
            if(!String.IsNullOrEmpty(_userName))
                Text = "Currently Logged In: " + _userName;
        }
    }
}

And again, on the Login Form button click handler:

var mainForm = new SalesForm();
mainForm.UserName = userName;
mainForm.Show();

Method

public class SalesForm : Form
{
    public void SetTitle(string userName)
    {
        Text = "Currently Logged In: " + userName;
    }
}

And:

var mainForm = new SalesForm();
mainForm.SetTitle(userName);
mainForm.Show();
Justin Niessner
Hi Justin,I am slightly confused (Still in the process of learning C#) could you Give me a little more detail on how it works, with possibly an example?sorry for any problems caused.Tom Kirby.
Tom Kirby
A: 

It is normally preferred to use the IServiceProvider pattern, but in small and trivial cases, static would be OK.

leppie
+1  A: 

I would not do this way you said. Is this a web application?

You should keep the user information and the business layer information separately. This will give you enough freedom to change the user information in the future if required.

For passing the transaction total, you should query the information from the database and show it to the web page. Can you do this?

You can also pass data using the following:-

 1. constructor
 2. objects
 3. properties
 4. Delegates
Karan
I too agree... Just calling a constructor a string of a person's name has nothing "behind the scenes" to directly associate a group of transaction / line items etc to complete a given sale. I would have a "class" object of LoggedInUser with such properties to get of name, description, cart total, etc yet have hidden elements like internal IDs.
DRapp
+1  A: 

When talking about authentication and authorization, you should create your own implementation of IPrincipal and IIdentity, which are then set within the Thread (Thread.CurrentThread).

The IPrincipal goes on the Thread and it holds onto your IIdentity. Your implementation can be queried to determine if the user is authenticated and what the user is allowed to do (see IsInRole).

As for using global variables to store information, that is not a good idea. However, you're starting out, so it might be good for you.

Alternatively, you could create public properties on your Forms where you set and, after the form is closed, get the results of user action on the form (don't forget, a form is an object just like anything else). So if form A instantiates form B, shows B modally, then gets control back after form B is closed, form A could then get the results (whatever they are) of user interaction from the properties on B.

public class B : Form
{
  // Set when the user completes a sale and closes the form with the OK button.
  public SaleItem Sale{ get; private set;}
}  

This is much better than using a global store for variables. If I were doing this, I'd use a dependency injection framework like Unity to get instances of classes that provide for functions such as sales within my application.

Will
A: 

For a small, simple application when you're just getting started, static variables can help get things running, but it's not a habit you want to get into. You might start by writing down all of your state variables in one place, but then step back and take the time to think about where you actually use them. If some of the variables are only used in one small part of the program, try to think of ways to hide them from the rest of the program, such as by putting them in a class that only that part of the program is given an instance of. As you write your program, take breaks periodically, look at your classes and think about the following:

  1. Encapsulation : Is my class doing a well-defined job or is it trying to do all sorts of different things? If you can't immediately figure out what the job-description of the class is, then it's probably doing too much. Consider breaking the functionality off into smaller pieces that you can work on individually.

  2. Insulation: Is my class exposing information that other classes shouldn't need to know about it? I should only tell other classes what they need in order for them to use me for my job. I also need to prevent other classes from interfering with my job as best I can. If other classes use me incorrectly, I should complain loudly (throw exceptions) so that the developer realizes that something is wrong.

  3. Non-repetition: Do I have pieces of code that look very similar, with only slight modifications between them? Try to find a way to consolidate these pieces of code into a single method and call that method from each location. If you ever find yourself fixing a bug and having to go to multiple locations in the code to apply the fix, this is a sign that you're repeating yourself. Invest the time to fix this and it will be beneficial in so many ways in the future.

These principles are all designed to help manage complexity, by helping you to understand your code and by limiting the possibility for bugs by minimizing the number of possible interactions between portions of code. Enjoy learning. :)

Dan Bryant