Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

A simple library catalog system in C#

0.00/5 (No votes)
15 Nov 2007 1  
This article describes a simple library catalog system developed in C# which can be used as the foundation.

Introduction

In this article we will be examining the functionality made possible by inheritance and polymorphism. Note that this application requires you to login to begin with. Three logins are created when the application starts, one for each type of user:

Administrative User
Login: admin
Password: admin
Staff Member User
Login: staff
Password: staff
Student User
Login: student
Password: student

You can create further users when the program is running under the menu for the administrative user.

There are two inheritance hierarchies used within the provided code, a hierarchy representing different types of users, and a separate hierarchy representing different catalog items.

The MenuBuilder class defines what items will appear in each of the menus presented to the user. The User Management allows for different user objects to be created: an Admin user, a Student user, and a Staff user. Describe, step by step, how the application creates these objects and obtains the information required for their attributes.

#region Catalogue Management Menu

public static void CatalogueManagementMenu(Users.User usr, out ExtendedResult result)
{
    SortedList<string, MenuOption> menu = new SortedList<string, MenuOption>();
    menu.Add("B", new MenuOption("B", "Add new book", new MenuHandler(AddBookHandler)));
    menu.Add("P", new MenuOption("P", "Add new periodical", new MenuHandler(AddPeriodicalHandler)));
    menu.Add("X", new MenuOption("X", "Exit", new MenuHandler(LogoutHandler)));
    result = new ExtendedResult(ResultCode.SubMenu, menu);
}

#endregion

#region User Management Handlers

private static void AddUserHandler(Users.User usr, out ExtendedResult result)
{
    SortedList<string, MenuOption> menu = new SortedList<string, MenuOption>();
    menu.Add("A", new MenuOption("A", "Administrator", new MenuHandler(AdministratorHandler)));
    menu.Add("M", new MenuOption("M", "Staff Member", new MenuHandler(StaffMemberHandler)));
    menu.Add("S", new MenuOption("S", "Student", new MenuHandler(StudentHandler)));
    menu.Add("X", new MenuOption("X", "Go Back", new MenuHandler(GoBackHandler)));

    result = new ExtendedResult(ResultCode.SubMenu, menu);
}

The creation of a user is done by invoking the AutoPrompt.Create<>() generic function, with the particular user indicated inside the <> (Users.Admin, Users.Staff, or Users.Student).

The Create<>() function creates one of the new objects (represented by 'datatype') then passes this new object by reference to the CreateWorker<>() function along with an indication of its datatype (typeof(datatype)).

public static datatype Create<datatype>() where datatype : new()
{
    datatype dt = new datatype();
    CreateWorker<datatype>(ref dt, typeof(datatype));
    return dt;
}

The CreateWorker<>() function

  1. Immediately returns if the data type indicated is type object, otherwise recursively calls itself, passing the same object through but instead indicating the next ancestor class type (base type). Thus, in the hierarchy of types passed to CreateWorker, the first type that will actually be processed is the data type that is directly derived from type object, then the next child class, and so on, until the original type is reached.
  2. For the current type, a foreach loop is used to examine each of the NonPublic (i.e., private or protected), Insance members (i.e., non-static members)
    1. If the type is a Field (i.e., attribute)
      • Attempt to retrieve the AutoPrompt code attribute, if there is no such code attribute then move onto the next member identified by the loop at (b) above.
      • Retrieve the prompt specified in the AutoPrompt code attribute
      • Depending on the data type (the large if/else-if statement), prompt the user for the appropriate data and then store it into the object (fi.SetValue stores the value).
private static void CreateWorker<datatype>(ref datatype obj, Type t)
{
    if (t == typeof(object))
    return;
        CreateWorker<datatype>(ref obj, t.BaseType);

        foreach (MemberInfo mi in t.GetMembers(BindingFlags.NonPublic | BindingFlags.Instance))
        {
          if (mi.MemberType == MemberTypes.Field)
            {
              AutoPrompt ap = Attribute.GetCustomAttribute(mi, typeof(AutoPrompt)) as AutoPrompt;
              if (ap == null)
                continue;

        FieldInfo fi = mi as FieldInfo;
        string fieldPrompt = ap.PromptText;

Points of Interest

There are two inheritance hierarchies used within the provided code, a hierarchy representing different types of users, and a separate hierarchy representing different catalog items.

History

  • November 16, 2007

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here