Goals: Class Example 1-5: With - Separate - Lib

Download as pdf or txt
Download as pdf or txt
You are on page 1of 4

Class Example 1-5 : with_separate_lib

Corresponding MFC Version: 5.with_separate_lib (Week 1, Fall 2003)

Goals
• Extend class example 4.
• Add a new project to the solution. The new project is called GraphicsAPI.
• Add a Utility class the new project.
• Set up the references and dependencies between the projects in the solution.
• Introduce changes dealing with namespaces to keep things neat and clean.

Note: In my sample code, I recreated the solution to have its own folder, where the ClassExample
project folder is a subfolder of the solution. If you decide not to do this, then the project and
solution files will be under a single ClassExample folder. Everything will still work of course; it just
seems a little less “clean” in my opinion. See my tutorial Creating Windows Forms App with C# for
more information on this setup. This is just a suggestion and is not required. I use this setup for
the rest of the class examples.

Steps
1. Since this example requires and extends ClassExample 1 - 4, you can just build onto the work
done in ClassExample 4 to avoid duplicating work.

2. Change the Text property of Form1 to: Now we have a lib and RANDOMness!!

3. First we need to add a new C# Class Library project to the solution.

a. From the main menu, choose File | New | Project.

i. Select a Visual C# Class Library Template.


ii. Name the project GraphicsAPI
iii. Make sure to select the Add to Solution radio button.
iv. Click the OK button.
4. After you click the OK button a new project will be added to the solution. By default it includes a
file called Class1.cs. We’re going to change that file to something useful.

a. First, let’s change the name of the file. In the Solution Explorer, right-click the class1.cs
file and choose Rename from the context menu. Change the name to Utility.cs.

b. Next, we will highlight all of the code in the file delete it.

c. Now type in the following code. Note that comments have removed. Please see the
sample code for comments.

using System;

namespace CSS450and451
{
namespace GraphicsAPI
{
sealed public class Utility
{
private static System.Random random;

private Utility() {}

static Utility()
{
random = new System.Random();
}

static public float RandomNumber(float range)


{
return range * (float)random.NextDouble();
}

static public float RandomNumber(float min, float max)


{
float range = max - min;
return min + RandomNumber(range);
}

static public void RandomTriple(float min, float max, float[] t)


{
t[0] = RandomNumber(min, max);
t[1] = RandomNumber(min, max);
t[2] = RandomNumber(min, max);
}
}
}
}

5. Save the Solution.

6. The ClassExample solution now contains two projects – the


original ClassExample Windows Application project and the
new GraphicsAPI class library project.
7. Our application is dependent upon the GraphicsAPI class library because we want to use the
RandomNumber method of the Utility class. We need to add a reference to GraphicsAPI in the
ClassExample project. This allows us to actually use its types such as the Utility class.

a. Make sure that the ClassExample project is selected in the Solution Explorer.

b. On the main menu select Project | Add Reference (or right-click the project in the
Solution Explorer and choose Add Reference from the context menu).

c. After the Add Reference dialog opens, choose the Projects tab and select the
GraphicsAPI project. The GraphicsAPI class library will be added to the Selected
Components list. Click the OK button.

8. Now the types in the GraphicsAPI class library can be referenced. In other words, you can now
use the types in the library as part of the ClassExample project.
9. Now you want to add a using directive to the top of the Form1.cs file so that you don’t have to
fully qualify the Utilities class. I’ve put the GraphicsAPI class library into the CSS450and451
namespace. That way, if someone else makes a GraphicsAPI class library, you can resolve
naming collisions.

using CSS450and451.GraphicsAPI;

10. Make the following changes to the timer1_Tick event handler. Notice that you can now use the
Utility class and its static RandomNumber method:

private void timer1_Tick(object sender, System.EventArgs e)


{
tickCount++;

if (tickCount >= 40)


{
secondsCount++;
// Use the static RandomNumber method from the
// GraphicsAPI Utility class.
float randomNumber = Utilities.RandomNumber(10);
statusTextBox.Text =
string.Format("{0} seconds have passed. Current random number: ({1})",
secondsCount, randomNumber);
tickCount = 0;
}
}

11. On the main menu, choose Build | Build Solution ( or Ctrl+Shift+B ).


Because the ClassExample project is dependent upon the GraphicsAPI class library project, the
GraphicsAPI project is built first, then the ClassExample is built last. If the build is successful,
you’ll get the message in the Visual Studio .NET Output window:

---------------------- Done ----------------------

Build: 2 succeeded, 0 failed, 0 skipped

Differences from the MFC version


• In MFC, the RandomNumber functions are all global. We can’t have global methods in .NET.
because everything must be in a class, interface, or struct. To get around this I have created a
class that will hold these global “utility” methods. They are static and so can be called without
having to instantiate the class.

• In fact the Utility class is special in two ways.


1. The class is sealed, meaning that it can’t be inherited from.
2. It has a private constructor, meaning that no instances of the class can be made. This is
a design pattern for classes that will only contain static methods.

• The MFC version of RandomNumber uses a static variable called FirstTime that is used to
perform a one time seeding of the random number generator (RNG). In C#, we have the static
class constructor. The static class constructor is used for class-level initialization. There is only
one allowed in a class and it is guaranteed to be called before an instance of the class is created.

• The call to the .NET Framework class System.Random in our Utility class’s static constructor
uses a time-based seed. So there is no corresponding srand function like the C/C++ world.

• If you look in the ClassExample\bin\Debug folder you will see that a copy of the
GraphicsAPI.dll has been created there. This is because ClassExample.exe is dependent on
GraphicsAPI.dll. Obviously, the same is true for the release builds.

You might also like