Sunday, April 29, 2007

ADO.net - DataSet vs. DataReader

ADO.net
  • DataSet vs. DataReader
DataReader [while(r.Read())]

When a database query is being executed, DataReader reads the rows one by one and populates the result, let's say on the web page making the request.
Important feature: Data is displayed as soon as partial results become available.
-Works as read-only. Can't update the DB.
-Always maintains connection.

DataSet [foreach(...)]

-Important feature: Data is not displayed until the whole result of the query is received. Once we get the whole result, we can start displaying the rows of data.
-Shouldn't be considered as a local copy of a DB. Can hold data from different tables and relate them.
-Enables operations like binding.
-Provides flexibility to create a datatable on the memory, on-the-fly.

DataAdapter

is used to retrieve data from a DB. Can also update the DB back.


  • Examples: (DataSet File name: DataSet1.xsd)

DataReader example:

private void Query_Click(object sender, EventArgs e)
{
// NO SqlDataAdapter IS NEEDED!!!
SqlConnection objConn = new SqlConnection();
objConn.ConnectionString = "Data Source=hc\\sqlexpress; integrated security=SSPI; Initial Catalog=ContructionProject";

objConn.Open();
SqlCommand objCmd = new SqlCommand("myStoredP_1", objConn);
objCmd.CommandType = System.Data.CommandType.StoredProcedure;

SqlDataReader myreader = objCmd.ExecuteReader();

while (myreader.Read())
{
listBox1.Items.Add(myreader[0].ToString()+" " + myreader[1].ToString());
}

objConn.Close();
}

DataSet example with Fill() method:

private void myDataSet_Query_Click(object sender, EventArgs e)
{
SqlConnection objConn = new SqlConnection();
objConn.ConnectionString = "Data Source=hc\\sqlexpress; integrated security=SSPI; Initial Catalog=ContructionProject";
objConn.Open();
SqlCommand objCmd = new SqlCommand("myStoredP_1", objConn);
objCmd.CommandType = System.Data.CommandType.StoredProcedure;

SqlDataAdapter a = new SqlDataAdapter(objCmd);
DataSet1 s = new DataSet1();
a.Fill(s, s.myStoredP_1.TableName);

foreach (DataSet1.myStoredP_1Row dr in s.myStoredP_1.Rows)
{
MessageBox.Show(dr.FName.ToString());
}

//foreach (DataRow dr in s.Tables[0].Rows)
//{
// MessageBox.Show(dr[1].ToString() + dr[0].ToString());
//} /*This foreach loop works as well*/

objConn.Close();
}

DataSet example with GetData() method:

private void DataSet_GetData_Click(object sender, EventArgs e)
{
// NO NEED TO USE SQLCOMMAND OR CONNECTION STRING!!

DataSet1 dseg = new DataSet1();
DataSet1TableAdapters.myStoredP_1TableAdapter egAdap = new DataSet1TableAdapters.myStoredP_1TableAdapter();

DataSet1.myStoredP_1DataTable dt = egAdap.GetData();
foreach (DataSet1.myStoredP_1Row dr in dt.Rows)
{
listBox1.Items.Add(dr.ID + " " + dr.FName);
}

}

* ADO.net does not support bulk inserts to the DB!
* System.Data namespaces: SqlClient, OleDb, ODBC, OracleClient
* Use of ODBC is discouraged because it is slow, unsecure and has limited functionality.
* Oracle: No multiple SELECT statements!

Friday, April 27, 2007

C# programming notes



  • Two references to the same object--Interesting!!!



Source: C# 2005 for Dummies, Wiley.

Important Subjects

Single point of failure


Load balancing

High-availability

Caching


thin client

thick client


Replay Attacks


Proxy

Credentials

Single sign-on

ClearTrust
Strong password -Weak password

Connection Pool

Windows Service

Monday, April 23, 2007

Web.config

WEB.CONFIG file in a web application

  • Allow / Deny users
Below code will deny access to the anonymous users and Windows users with a Guests Role. However, the user yyyy under xxx domain will be granted access.


allow users="xxx\yyyy">
deny users="?">
deny roles="Guests">

  • WARNING!
allow users="*">
deny users="yyyy">


Due to the design of .NET, the above will grant access to all authenticated users even though yyyy seems to be denied!

  • When WEB.CONFIG is updated (even with an insignificant change, like addition of a space character)
-The entire web application will be forced to restart This is an enhancement over .NET 1.1
-What if, I don't want my application to restart each time an update is made to WEB.CONFIG in .NET 2.0?
Solution: Create another configuration file like easy.config and put the most frequently changing setting in this file.

appsettings configsource="easy.config">

Good practice: Create a seperate config file for Connection Strings.

Adding a key & value pair in WEB.CONFIG:

appSettings>
add key="x" value="5"/>
/appSettings>

  • Publishing the site locally:
This is also an enhancement in .NET 2.0. Whenever we publish the site locally, the .NET framework creates a .dll and the .aspx files for our access.
This is especially useful if we don't have IIS (Internet Information Services) installed.
We can easily debug our web application in our local PC.

  • Reconfiguration of ASP.NET: (a real-time problem)
In some instances, we may need to reconfigure ASP.NET.
(For example, if the IIS was installed later than ASP.NET.)

run the ASP.NET reconfiguration utility:

> aspnet_regiis.exe -u (for uninstallation)
> aspnet_regiis.exe -i (for installation)

  • BONUS knowledge for IIS:
Suppose that somebody is continuously trying to access your ftp site.
The person is not granted access but the bandwidth will be used unwantedly.
I can get the IP address of this unwanted internet user by checking my log file. And I want to block this IP addresss from my ftp site.
IIS can not do this! (Even though it can not, it is good to know :) )
However, this IP-denial can be achieved in proxy-level. HOW??

NET Remoting, Web Services etc.

Web Service concepts

  • .NET Remoting

It is mainly related to interprocess communication.
The processes can be within the same computer, computers on the same network or even the computers across different networks.
.NET Remoting enables these remote processes to communicate with each other.
.NET Remoting supports communication over different protocols.

In the past, the interprocess communication was handled by DCOM (Distributed-Component Object Model). But DCOM did not support different platforms and had some drawbacks related to firewalls. It communicated over ports that are usually blocked by firewalls. (can we still call the firewall a "firewall" if many ports are open?? ) Port 80 might be used but in that case, the firewall has to support binary traffic on port 80. (Q: What is binary traffic?)

Now that we have some practice with Web Services, we can compare it to .NET Remoting.

What was Web Services anyway??
-Web Services enable applications to pass messages to each other regardless of their platform, programming language and object model.
-Web services know nothing about the client making the request.
-It only receives a message and responds to it in a format called SOAP (Simple Object Access Protocol).

*Web Services ONLY use HTTP protocol to communicate. .NET Remoting can use any protocol!
*Web Services is stateless and creates a new object each time it receives a request. .NET Remoting has state management options, supports callbacks.
*Objects are serialized using XML included in SOAP messages. No other way than XML in Web Services. .NET Remoting does not work if the data types are not defined. This is a limit to using different data types if there is not support for it. However, objects can be passed by value or by reference.
*Web Services can operate across different platforms. .NET Remoting requires the applications built on .NET.


In .NET remoting, the communication occurs over channels. The applications use the channels to send or receive messages. There are two existing channels: TcpChannel and HttpChannel in .NET Remoting.

Below is a snapshot of the application I have tested. The one on top is the Server. The window at the bottom is the client making the request. The Server responds to the client with a message.



Links:
http://www.developer.com/net/cplus/article.php/10919_1479761_1


  • SOAP (Simple Object Access Protocol)

SOAP is a protocol that enables the applications to communicate across the computer networks.
The communication is achieved by using XML format.
The communication occurs usually using HTTP.

Below is a snapshot of the soap messages created by the HelloWorld Web Service that we have created. The top block makes the request and the bottom block displays the corresponding response.
Note that, only the return types are specified, not the returned values. Because the Web Service method has not been invoked yet.
OK, SOAP does this, SOAP does that. Where does this all fit in real-world? Where do I use SOAP? Please add the best practices of using SOAP to my post here.
There is one application I can only guess for the time being. It might not be correct though.
Let's take the example of a Small Business web site. Assume that, this site is selling computer parts. Nowadays, we see that there are options on the web site when we are about to make a purchase, like "Click here to check how many items are available." When you click this link, the small business web site connects to the Distributor's web site or database and queries the most current value. Of course, the distributor wouldn' t prefer to provide access to their database to everyone. They would prefer an interface instead. So, these kind of messaging between different web sites might be good application for SOAP. Remember, it is just my understanding and might not be true.

  • XML (Extensible Mark-up Language)

XML is like HTML. The main difference is that we can specify and use our own tags.
Every tag has to have a closing tag OR needs to be self-closing, using the forward slash /.
Needs to conform to the rules of being Well-formed.
Needs to be valid.

For months, I have not understood why XML became so popular! You see books written on XML everywhere, people talk about it etc. Still having trouble understanding it.

For example, Microsoft has released Small Business Starter Kit in ASP.NET. Using this kit, you can advertise your products, display their pictures, specify the price, edit the definition etc. All these features of the product are defined within an XML file. You can easily edit these attributes I mentioned (item definition, price etc.) even by a text editor. For instance, the previous price of item A is $1175, then open the XML file and easily change it to $1250. But, what if you need to update each of the one-thousand items' prices?! See my post in ASP.NET forums. http://forums.asp.net/thread/1408825.aspx

My only understanding is that, the XML format is both machine and human readable format. Everything is written in simple text and there is no encryption. For instance, you can not easily access a database so easily; you need to have at least MS Access installed to access your tables, in case of an Access Database. SQL server requires correct connection string, username/password etc. Why bother with these? Open the XML document with your Notepad and reach the information you need and even edit the file yourself!

  • WSDL (Web Service Definition Language) - wsdl.exe

-Having its description based on XML, WSDL defines the communication used on Web Services.
-The services are described as a collection of ports (or network endpoints).
-The definitions are abstract and they are separated from the actual use which clarifies the ports being used at that instance. This allows to use the same codes again and again.
-The client connects to the web site and uses WSDL to discover what services are offered.
-After determining the available services, one of the functions or methods can be called using SOAP.

  • Web Services Discovery Tool - disco.exe
-Discovers (queries, interrogates) and saves the documents of each of the XML Web Services in a particular web site to the local disk.
-disco.exe and wsdl.exe are used in conjunction with the web services.
-Produces .wsdl, .disco, .xsd and .discomap files which can later be used by wsdl.exe as an input to create XML Web Service clients.
1. Use disco.exe to discover available services and download
2. Then use wsdl.exe to produce the proxy files.
3. Compile the project.

Generating a proxy class for our code (When we are not allowed to add a web reference)
> wsdl /out:C:\Webservice_HelloWorld.cs C:\Webservice_HelloWorld.wsdl

1. wsdl parses the web service description.
2. Generates proxy classes.
3. Consumer uses these proxy classes to call the methods of that particular web service.

A useful link for above process.

-Not all web services have to provide support for public discovery. It can be used privately.

  • UDDI (Universal Description Discovery and Integration)
is an XML-based registry for businesses to list their company on the internet.
The companies can list themselves with name, location... and the web services they offer.
By this way, companies can have their systems inter-operating with other companies.

Case study: Different types of digital photography software do not inter operate and many people find it difficult to print their digital photos. The companies producing digital cameras have come together to support networks where end-users can easily have their digital photos printed.

Delegates, Reflections, INVOKE

Delegates:
-Similar to pointers in C++.
-Has something to do with Callback functions.
-Generic delegate copy is created at the run-time.

Reflections:
-Enables us to query the namespaces, methods...

foreach statement:
-Quite useful when there is an array of strings, or an array of ints, or an array of objects to talk about. Simply, an array of something.

Below program section makes use of the Reflections and foreach statement and used to query the methods in a .dll file. The methods are added to the listbox in the Windows form.

Notice the return types of below methods: They are arrays.
Type[] Assembly.GetTypes();
MethodInfo[] Type.GetMethods();

private void Discover_button_Click_1(object sender, EventArgs e)
{
System.Reflection.Assembly cx = System.Reflection.Assembly.LoadFile(textBox1.Text);

foreach (Type t in cx.GetTypes())
{

foreach( System.Reflection.MethodInfo mi in t.GetMethods())
{
listBox1.Items.Add(mi.Name);
}

}

}

Use the code below to easily select the .dll file you need. Don't forget to add a OpenFileDialog and an Open File button to your design.

private void OpenFile_button_Click(object sender, EventArgs e)
{
openFileDialog1.ShowDialog();
string filename = openFileDialog1.FileName;
textBox1.Text = filename;
}

BONUS QUESTION:
-We have queried the methods in our CalculateInterest Class Library. The query produced two methods: CalculateSimpleInterest() & CalculateCompoundInterest().
-Now, how can we actually run the CalculateSimpleInterest() method and learn the interest for a given principal, rate and time?

We have to INVOKE this function to achieve the above purpose.
Research Activator.Getobject() method!

Thursday, April 19, 2007

UML: Unified-Modeling Language

Defined by OMG (Object Management Group).
Set of graphical components that model the objects and the relationships between them.

Let's consider the case of construction business.
Architects design the buildings and builders use these designs to realize what is described in the blueprints. Blueprints are a common language between architects and the builders.

Similarly, UML standard is a common language between all software developers. Apart from the implementations, all members of a team can see the classes and objects used in the design, which is especially useful in situations where the design is quite complex.

UML has nine modelling diagrams. The first three are below:

  • Use case diagrams
  • Describes what a specific model does. (Not how it does that!)
  • Class diagrams
  • Displays all of the classes in a system and the inter-relationships between classes. Name, Attributes and Operations of each class are displayed. (Does not give any idea what happens when the classes interact!)
  • Object diagrams
  • Displays the objects being used, instead of classes. (An object is an instance of a class) Like a university has multiple departments, we can have multiple objects of the same class. Object diagrams display all of the objects in the system.

  • Source: http://dn.codegear.com/article/31863

    Wednesday, April 18, 2007

    4. Finding the Weekday of a Given Date



    Is April 18, 2007 a Wednesday?
    This program asks the user to enter a random date, like 4/18/2007.
    Then it will tell you the weekday, like Wednesday.



    I am encouraging the readers of this title to refer to this link first. It is the source for my implementation. It is a more general approach rather than a simple calculation.

    Program.cs

    using System;
    using System.Collections.Generic;
    using System.Text;

    namespace DayFinder
    {
    class Program
    {
    static void Main(string[] args)
    {
    Date D = new Date(); // Don't need my coding to define the constructor.
    Console.Write("Enter month: ");
    D.month = uint.Parse(Console.ReadLine());
    Console.Write("Enter day: ");
    D.day = uint.Parse(Console.ReadLine());
    Console.Write("Enter year (yyyy): ");
    D.year = uint.Parse(Console.ReadLine());

    Console.WriteLine("You have entered: "+D.month+"/"+D.day+"/"+D.year);

    //Assuming the entries are legal:
    /*********************************************
    For July 13, 1989:
    1. Divide the last two digits of the year by 12. 89 divided by 12 is 7, with 5 left over.

    2. Find how many 4's go into the remainder evenly. 5 divided by 4 is 1, with a remainder that we ignore.
    3. Add these three numbers. 7 + 5 + 1 = 13.
    4. Divide the sum by 7 and take the remainder. 13 divided by 7 is 1, with a remainder of 6.
    5. Add the remainder to the century's anchor day to find the year's Doomsday. Wendesday + 6 = Tuesday.
    6. Use the month's Doomsday to find the day you need. July's Doomsday is 7/11, a Tuesday, so July 13 is a Thursday.
    Source: http://www.theworldofstuff.com/other/day.html
    *********************************************************/

    uint yearTwoDigits = D.year % 100;
    uint ydivision = yearTwoDigits / 12;
    uint yremainder = yearTwoDigits % 12;
    uint NumberOfFours = yremainder / 4;
    uint FinalRemainder = (ydivision + yremainder + NumberOfFours) % 7;
    uint AnchorDay = UtilityFunctions.GetAnchorDay(((uint) (D.year/100) * 100) % 400);

    uint YearsDoomsDay = (FinalRemainder + AnchorDay) % 7;
    int difference = (int) D.day - (int) UtilityFunctions.GetMonthsDoomsDay(D.month, D.year);
    int ExactDay = (int) YearsDoomsDay + difference; //Need typecasting
    if (ExactDay <0) face="courier new">ExactDay += 7;
    else if (ExactDay > 7)
    ExactDay=ExactDay % 7;

    string WeekDay=UtilityFunctions.GetExactDay(ExactDay);

    Console.WriteLine("This date is a "+WeekDay);
    Console.Read();
    // Logic Errors: 2/29/2007 => Thursday. There is no such 2/29 in 2007!
    // Day undefined for 7/3/1989!
    }
    }
    }


    UtilityFunc.cs

    using System;
    using System.Collections.Generic;
    using System.Text;

    namespace DayFinder
    {
    class Date
    {
    public uint month; //public is needed!
    public uint day;
    public uint year;
    }


    class UtilityFunctions
    {

    public static uint GetAnchorDay(uint AnchorCheck)
    {
    uint AnchorDay= 0;
    switch (AnchorCheck)
    {
    case 100:
    AnchorDay = 0; //"Sunday"
    break;
    case 200:
    AnchorDay = 5; //"Friday"
    break;
    case 300:
    AnchorDay = 3; //"Wednesday"
    break;
    case 0:
    AnchorDay = 2; //"Tuesday"
    break;
    }
    return AnchorDay;
    }
    public static int GetMonthsDoomsDay(uint Month, uint Year)
    {
    int DoomsDay = 0;
    switch (Month)
    {
    case 1: //January
    DoomsDay = 3 + (int)isLeap(Year);
    break;
    case 2: //February
    DoomsDay = 28;
    break;
    case 3: //...
    DoomsDay = 0;
    break;
    case 4:
    DoomsDay = 4;
    break;
    case 5:
    DoomsDay = 9;
    break;
    case 6:
    DoomsDay = 6;
    break;
    case 7:
    DoomsDay = 11;
    break;
    case 8:
    DoomsDay = 8;
    break;
    case 9:
    DoomsDay = 5;
    break;
    case 10:
    DoomsDay = 10;
    break;
    case 11:
    DoomsDay = 7;
    break;
    case 12:
    DoomsDay = 12;
    break;
    }
    return DoomsDay;
    }
    internal static uint isLeap(uint Year)
    {
    if ((Year % 4) == 0) return 1;
    else return 0;
    }
    public static string GetExactDay(int ExactDay)
    {
    string WeekDay=null;
    switch (ExactDay)
    {
    case 0:
    WeekDay = "Sunday";
    break;
    case 1:
    WeekDay = "Monday";
    break;
    case 2:
    WeekDay = "Tuesday";
    break;
    case 3:
    WeekDay = "Wednesday";
    break;
    case 4:
    WeekDay = "Thursday";
    break;
    case 5:
    WeekDay = "Friday";
    break;
    case 6:
    WeekDay = "Saturday";
    break;
    }
    return WeekDay;
    }

    }
    }

    3. Doubly-linked list

    In addition to the properties of the singly-linked list, each node in a doubly-linked list contains a link to the previous node in the chain.
    Program.cs


    using System;
    using System.Collections.Generic;
    using System.Text;

    namespace Doubly_LinkedList
    {
    class Program
    {
    static void Main(string[] args)
    {
    char Answer = 'y';
    Node n;
    Node head = new Node();
    Node currNode;
    Node TempNode;
    currNode = head;

    while (Answer == 'y')
    {
    n = new Node();
    Console.Write("Enter Node Data: ");
    n.Data = int.Parse(Console.ReadLine());
    TempNode = currNode;
    currNode.Next = n;
    currNode = n;
    currNode.Prev = TempNode;

    Console.Write("Answer (y/n): ");
    Answer = char.Parse(Console.ReadLine());
    }

    Console.WriteLine("Printing the Node Data: (Forward)");

    TempNode = head;
    while (TempNode.Next != null)
    {

    TempNode = TempNode.Next;
    Console.WriteLine(TempNode.Data);
    }

    Console.WriteLine("Printing the Node Data: (BACKward)");

    do
    {
    Console.WriteLine(currNode.Data);
    currNode = currNode.Prev;
    } while (currNode != head);

    Console.Read();
    }
    }
    }


    Node.cs

    using System;
    using System.Collections.Generic;
    using System.Text;

    namespace Doubly_LinkedList
    {
    class Node
    {
    public Node()
    {
    Data = 0;
    Next = null;
    Prev = null;
    }
    public int Data;
    public Node Next;
    public Node Prev;
    }
    }

    2. Singly-linked list




    Each node consists of one data member and one link to the next node. The last node in the chain will always point to a null value.

    My implementation consists of two cs files including two classes.

    Program.cs

    using System;
    using System.Collections.Generic;
    using System.Text;

    namespace myLinkedList
    {
    class Program
    {
    static void Main(string[] args)
    {
    char Answer='y';
    Node n;
    Node head=new Node();
    Node currNode;
    currNode = head;

    while (Answer == 'y')
    {
    n = new Node();
    Console.WriteLine("Enter Node Data:");
    n.Data = int.Parse(Console.ReadLine());
    currNode.Next = n;
    currNode = n;

    Console.WriteLine("Answer (y/n): ");
    Answer=char.Parse(Console.ReadLine());
    }

    Console.WriteLine("Printing the Node Data:");

    while (head.Next != null)
    {

    head = head.Next;
    Console.WriteLine(head.Data);
    }

    Console.Read();


    }
    }
    }


    myNode.cs

    using System;
    using System.Collections.Generic;
    using System.Text;

    namespace myLinkedList
    {
    public class Node
    {
    public Node()
    {
    Data = 0;
    Next = null;
    }
    public int Data;
    public Node Next;

    }
    }

    OVERVIEW:
    Although, this program produces the output I desire, it causes a memory leak, doesn't it?

    Notice the line: head = head.Next;

    There is a virtual head node that is hidden. If we intended to create 3 nodes, the program actually creates 4 nodes. Then it starts printing the data by skipping the first node.

    Tuesday, April 17, 2007

    ClassLibrary: Creating dll files

    As opposed to running a C# application as a Console application, we can define it as a ClassLibrary and include it within the other programs we are gonna implement in the future.

    The main differences of a console application is as follows:



    • Console: The compiled file's extension is .exe so it is executable.
    • ClassLibrary: The compiled file's extension is .dll thus it is NOT executable by itself. However, it is well suited for inclusion by other programs.

    ClassLibraries may be used in two ways:

    1. Private
    2. Public

    for Private ClassLibraries:
    Does it happen when we SIGN and explicitly select the .dll file in Visual Studio, under Project properties??

    As for the public ClassLibraries:
    The .dll file may be published to a global folder under Windows directory. So, any application can use it.


    This process can be done as follows:
    First of all, the project must be created as a ClassLibrary in Visual Studio.
    Then implement the program codes just like I did in InterestCalculation program in the previous post. Compile the program. This will produce the .dll file.
    Then go to VS Command Prompt and run this: > sn -k c:\easy.snk
    You will get: > Key pair written to c:\easy.snk

    1. Next thing to do is to use .NET GLOBAL ASSEMBLY CACHE utility.
    2. In the command prompt, type: > gacutil -i C:\{Location of the .dll file}\InterestCalculation.dll
    3. This won't work: You'll get the following error: > Failure adding assembly to the cache: Attempt to install an assembly without a strong name.
    4. The reason was because we haven't digitally signed the project of ClassLibrary. This digital signature is a randomly generated key specific to each of the persons. This is what we did in the 1st step above.
    5. Go to Project Properties (Right-click in Solution Explorer) and switch to SIGNING TAB.
    6. Enable checkbox "Sign the Assembly." Choose a strong name key file. Browse and select the key file [C:\easy.snk in this example].
    7. Now re-do the 3rd step above.
    • This procedure required a minor fix in our case. In Visual Studio 2003, we had to correct the line [assembly: AssemblyKeyFile("")] as [assembly: AssemblyKeyFile(@"C:\easy.snk")]
    • I have Visual C# 2005 Express in my computer. Unfortunately, the above correction was NOT successful and now I am not able to install the assembly to global directory. If anybody has a idea about this, please post it to my blog. Thanks!

    Overview:

    The Global Assembly Cache is so useful to share the previously written program codes. This is a PUBLIC method of sharing the codes among applications. So, what is the PRIVATE method to accomplish this??

    Let's assume that two developers Gerry and Jerry are team members for software development. They are responsible for implementing their own part. However, by mistake, they have used SAME namespace names in the implementation! What will happen during compilation of the project??

    The Strong Name Tool (SN.exe) enables us to sign our assemblies with strong names. For the example above, even though Gerry and Jerry used same namespaces by mistake, the digital signing of the application will prevent any compile errors and enable each of the developers to use even the same names for namespaces and classes.

    1. Interest Calculation

    This is the first Console program I have written in the C# & .NET class:

    Program.cs


    using System;
    using System.Collections.Generic;
    using System.Text;


    namespace Interest
    {
    class Program
    {
    static void Main(string[] args)
    {
    Console.WriteLine("Enter the money (p):");
    int p = int.Parse(Console.ReadLine());
    Console.WriteLine("Enter the rate of interest (R):");
    double R = double.Parse(Console.ReadLine());
    Console.WriteLine("Enter the time (T):");
    int T = int.Parse(Console.ReadLine());

    InterestCalc IC = new InterestCalc();
    Console.WriteLine("Simple Interest:");
    Console.WriteLine(IC.CalculateSimpleInterest(p, R, T));
    Console.WriteLine("Compound Interest:");
    Console.WriteLine(IC.CalculateCompoundInterest(p, R, T));
    Console.Read();
    }
    }
    }




    InterestFunctions.cs



    using System;
    using System.Collections.Generic;
    using System.Text;

    namespace Interest
    {
    class InterestCalc
    {
    public InterestCalc()
    {
    }

    public double CalculateSimpleInterest(int p, double r, int t)
    {
    return (p*r*t)/100;
    }

    public double CalculateCompoundInterest(int p, double r, int t)
    {
    return p*(1+r/100)*t;
    }
    }
    }




    WHAT I HAVE LEARNED?

    The organization of the codes in C# consists of two main code blocks:

    1. namespace
    2. class
    namespaces can include different classes. We can place the codes of each of the classes in different files.
    -In this example, the class including the main program is named class Program{} and saved in Program.cs file.
    -On the other hand, the second class including the functions for the interest calculation is named class InterestFunctions{} and is saved in InterestFunctions.cs file.

    Both classes are implemented under the SAME namespace called namespace Interest{}.