My Portfolio

15
Windows Application Library Introduction: A database has been created to support the principal functions of a lending library’s day-to-day operations: adding new members (adult and juvenile) and checking books in and out. An assembly has been created that contains classes and interfaces that provide access to the database for these functions. What is needed is a Windows Forms-based front-end application that will provide a librarian with a visual interface through which he or she may perform the desired functions. Audience: This project is designed for library personnel to carry out typical library functions, such as add members and checking in/out library books. The forms were designed to be easy to use, adhering to windows forms best-practices and multiple document interface usage. Project Goals: • Design and develop a front end application that satisfies the following functionalities: Add Adult, Add Juvenile, Check In a book, Check Out a book, Add Book, Update Juvenile to Adult, Renew Card • Design the Presentation, Business and Data Access tiers • Develop code that is easily maintainable. • Provide validation for all required fields (see details below). • Provide adequate error handling. • Produce a user interface that is intuitive, requiring minimal training for users while minimizing resource utilization.

description

A portfolio of my library project and some .Net concepts

Transcript of My Portfolio

Page 1: My Portfolio

Windows ApplicationLibrary

Introduction:

A database has been created to support the principal functions of a lending library’s day-to-day operations: adding new members (adult and juvenile) and checking books in and out. An assembly has been created that contains classes and interfaces that provide access to the database for these functions. What is needed is a Windows Forms-based front-end application that will provide a librarian with a visual interface through which he or she may perform the desired functions.

Audience:

This project is designed for library personnel to carry out typical library functions, such as add members and checking in/out library books. The forms were designed to be easy to use, adhering to windows forms best-practices and multiple document interface usage.

Project Goals:

• Design and develop a front end application that satisfies the following functionalities: Add Adult, Add Juvenile, Check In a book, Check Out a book, Add Book, Update Juvenile to Adult, Renew Card

• Design the Presentation, Business and Data Access tiers

• Develop code that is easily maintainable.

• Provide validation for all required fields (see details below).

• Provide adequate error handling.

• Produce a user interface that is intuitive, requiring minimal training for users while minimizing resource utilization.

• Produce a user interface that is intuitive, requiring minimal training for users while minimizing resource utilization.

Page 2: My Portfolio

Database Manipulation (n-tier interaction)

Adding Adult private void aAButton_Click(object sender, EventArgs e) { aApicturebox.Visible = false;

if (aAfirstName.Text != string.Empty && aAlastName.Text != string.Empty && aAStreet.Text != string.Empty && aACity.Text != string.Empty && aAstate.Text != string.Empty && aAZip.Text != string.Empty) { BusinessLayer biz = new BusinessLayer(); // Create Business object for commincation to Library Access Data Layer. AdultMember Adult = new AdultMember(); // AdultMember is type declared in LibraryEntities. This allows population Adult.FirstName = aAfirstName.Text; // of AdultMember properties. Adult.LastName = aAlastName.Text; Adult.Street = aAStreet.Text; Adult.City = aACity.Text; Adult.State = aAstate.Text; Adult.ZipCode = aAZip.Text; toolStripContainer1.Text = biz.AddAdult(Adult); if ("Adult member added" == toolStripContainer1.Text) // Notify in various ways of success and new Member ID { aAsuccess.Visible = true; aAsuccessStatus.Text = String.Format(Adult.FirstName + " successfully added!"); aAsuccessID.Text = String.Format("Your member ID is now " + Adult.MemberID.ToString()); toolStripStatusLabel1.Text = "Adult successfully added"; } else { MessageBox.Show("Member could not be added to database. Please contact program Administator"); } } else // The required information was not provided by the user { MessageBox.Show("Please fill out required information to add Adult", "Adult Not Added", MessageBoxButtons.OK); } }

Here is a display of just one of the basic functionalities for the program at hand. The option of adding an adult to the database is available to the client by simply filling out information in the User Interface (UI). Provided with a series of textboxes, the information is gathered, passed through the Business Access layer and an AdultMember is added to the database. If required information is not provided, adequate error handling is applied to notify user of the issue.

Verifying Alpha Characters for Validationprivate bool VerifyCharacters(Control control) { Match nonchars = Regex.Match(control.Text, @"[^A-Za-z]");

// Does a match to make sure they aren't numbers if (nonchars.Success) { errorProvider1.SetError(control, "Must use alphabetical characters"); return true;

Page 3: My Portfolio

}

else { return false; } }

In every form where information is acquired through the user we must apply some sort of validation to constrain the intake information to the format or type we want. For adding a first name to AdultMember.FirstName property we must insure all characters are Non-numeric. Using Systems.Text.RegularExpressions we are able to validate to nearly anything we can think of. Here we provide a Regex Match statement to make sure all characters in the string match Alpha type characters.

Auto Correctprivate string AutoCaseCorrect(string name) { if (name != string.Empty) { string temp = name.Substring(0, 1); // Grabs first letter of text string return temp.ToUpper() + name.Remove(0, 1).ToLower(); //Concats first letter UpperCase and the rest letters LowerCase //then returns result } return string.Empty; }

No one wants to use a program that consistently throws errors even if the errors are valid mistakes made by the user. Here the program shows forgiveness. The correct format of firstName.Text entry is “Adrian” in order to be properly added to the database. First letter must be capitalized, the rest lower case. In the method AutoCaseCorrect as long as the data has been validated non-Numeric it will correct the format for the user and let validation of firstName.Text equal true instead of throwing an error on the UI.

Adding Adult through Business Layer after Validation /// <summary> /// Adds an Adult to the Library Data Access layer. Accepts an AdultMember /// object as parameter /// </summary> /// <param name="member"></param> /// <returns></returns> public string AddAdult(AdultMember member) { LibraryDataAccess lda = new LibraryDataAccess();

try { lda.AddMember(member); return "Adult member added"; } catch { return ErrorCode.AddAdultFailed.ToString(); }

}

Page 4: My Portfolio

After all validation has occurred, the Business tier AddAdult method is called passing through the Adult member information obtained by the top layer. This method calls the AddMember of the Library Data Access tier in a try block to handle any Exceptions that might be thrown. After success the appropriate status is communicated to the 1st tier.

Retrieving Data from Library Database Access Layer and Populating Form

private void historyInfoButton_Click(object sender, EventArgs e) { if (historyMemberID.Text != string.Empty) { short memberId = short.Parse(historyMemberID.Text); Member mymember = new Member(); //Member object to display in form BusinessLayer b1 = new BusinessLayer(); //BusinessLayer object to get Items on Loan from ItemsDataSet ids = b1.GetItemsOnLoan(memberId); //Library Database and member information to //populate DataGrid mymember = b1.GetInformation(memberId); if (mymember != null) { historyDataGrid.DataSource = ids.Items; //Display Items in Grid and Member Information in designated groupbox historygroupBox.Visible = true; historyDataGrid.Visible = true; historyFirstName.Text = mymember.FirstName; historyLastName.Text = mymember.LastName; historyStreet.Text = mymember.Street; historyCity.Text = mymember.City; historyZipcode.Text = mymember.ZipCode.ToString(); historyState.Text = mymember.State; historyExpiration.Text = mymember.ExpirationDate.ToString(); if (mymember.ExpirationDate < DateTime.Today) chkoutCardExpired.Visible = true; } else { errorProvider1.SetError(chkoutMemberID, "Must clear form before making another inquiry"); } } else { historygroupBox.Visible = false; } }

After data has been added to the database we need to support a retrieval of that information. Here an index of Member ID is inserted into a textbox control and using that information a query is started for the appropriate member information. The member information sets the Label.Text property on the UI. The ItemsOnLoan information is displayed through a DataGrid control by setting the DataGrids DataSource to the Library Data Access layers Items to the DataGrid.DataSource property.

Page 5: My Portfolio

Custom Stored Procedure in SSMS used to Check Out an Item

USE [library]GO/****** Object:  StoredProcedure [dbo].[CheckOut]    Script Date: 10/28/2009 12:43:19 ******/SET ANSI_NULLS ONGOSET QUOTED_IDENTIFIER ONGO/*CheckOut : Checks out a bookwritten: Adrian MartinDate 10/27/09Parameters:        ISBN,        Copy_no,        Member_no State Values:      'ISBN cannot be null value'               1      'Copy_no cannot be null value'            2      'Member_no cannot be null value'          3      'Item does not exist'                           4       'Item is already on loan'                       5      'Item was not able to be ckecked in'      6*/  CREATE PROC  [dbo].[CheckOut]

@ISBN       char(20)                = null,@Copy_no    smallint              = null,@Member_no  smallint

 AS BEGIN TRY--ValidationIF @ISBN is null      BEGIN            PRINT('ISBN cannot be a null value')            RAISERROR('ISBN cannot be a null value', 14, 1)      ENDIF @Copy_no is NULL      BEGIN            PRINT('Copy_no cannot be a null value')            RAISERROR('Copy_no cannot be a null value',14, 2)      ENDIF @Member_no is NULL      BEGIN            PRINT('Member_no cannot be a null value')            RAISERROR('Member_no cannot be a null value',14, 3)      END                  --Validate if item exist in libraryIF NOT EXISTS    -

  (                        Select isbn,copy_no FROM copy                        WHERE copy.isbn = @ISBN                        AND copy.copy_no = @Copy_no                      )        BEGIN                  PRINT('Item does not exist')                  RAISERROR('Item does not exist',14,4)      END--Validate item isn’t already on loan

Page 6: My Portfolio

IF EXISTS   (

                  Select isbn,copy_no,loanable FROM [Item Information]                  WHERE [Item Information].isbn = @ISBN                  AND  [Item Information].copy_no = @Copy_no                  AND [Item Information].on_loan = 'Y'                  )      BEGIN            PRINT('Item is already on loan')            RAISERROR('Item is already on loan', 14, 5)      END

--DO WORKELSE      BEGIN DECLARE @Out_Date datetime, --

  @Due_date datetime,  @Title_no int

            SET @Out_Date = GETDATE() --Check out Date equals TodaySET   @Due_date = DATEADD(WEEK,2,GETDATE()) --Due Date equals 2 weeks from TodaySET @Title_no =                   (                        SELECT title_no FROM [Item Information]                        WHERE [Item Information].isbn = @ISBN                        AND [Item Information].copy_no = @Copy_no                  )                              BEGIN TRANSACTION

 --Insert Check Out Item into the loan table            INSERT loan            (                  ISBN,                  copy_no,                  title_no,                  member_no,                  out_date,                  due_date            )                        VALUES            (                  @ISBN,                  @Copy_no,                  @Title_no,                  @Member_no,                  @Out_Date,                  @Due_date            ) --Update copy tables on_loan to Y    DECLARE @OnLoan varchar = 'Y'      UPDATE copy      SET on_loan = @OnLoan      WHERE copy.isbn = @ISBN      AND copy.copy_no = @Copy_no                        COMMIT TRANSACTION      ENDEND TRYBEGIN CATCH       IF @@TRANCOUNT <> 0 --If was in process of transaction rollback and raise error            BEGIN                  ROLLBACK TRANSACTION

Page 7: My Portfolio

                  PRINT('Item was not able to be checked out')                

  RAISERROR('Item was not able to be ckecked out',14,6)            END      print 'starting catch'      --local vars      DECLARE @ErrorMessage NVARCHAR(4000);      DECLARE @ErrorSeverity INT;      DECLARE @ErrorState INT;      --populate vars      SELECT @ErrorMessage = ERROR_MESSAGE(), @ErrorSeverity = ERROR_SEVERITY(),                   @ErrorState = ERROR_STATE();      -- rethrow goes to fron end c#      RAISERROR (@ErrorMessage, @ErrorSeverity, @ErrorState);      RETURN END CATCH

Here’s a glimpse at the work being done at ground level in a Stored Procedure. The Stored Procedure at hand is for checking out a book to the database. It accepts three parameters (@ISBN, @Copy_no, @Member_no), performs validation checks, and based on its ability to pass validation, begins a transaction to insert a row into the loan table with other items already checked out. If transaction isn’t able to occur the appropriate error is raised in a catch block with the error message, error state, and error severity.

Page 8: My Portfolio

/// <summary> /// Check out item checks out an item given memberID, isbn, and copynumber as parameters /// </summary> /// <param name="memberid"></param> /// <param name="isbn"></param> /// <param name="copyno"></param> public void CheckOutItem(short memberid,Int32 isbn, short copyno) { var ldc = new LibraryDataContext(); try { ldc.CheckOut(isbn, copyno, memberid); } catch { throw new LibraryException(ErrorCode.CheckOutFailed, "Check Out Failed"); } }LINQ provides an easy communication to our database, views, and its stored procedures. Here, the classes are set up based on drag and drop from our server and stored procedures create methods automatically for our database layer to use locally. By creating an instance of LibraryDataContext we can call our CheckOutItem stored procedure and pass the parameters necessary for accurate action.

Page 9: My Portfolio

Library Final Product

Page 10: My Portfolio
Page 11: My Portfolio
Page 12: My Portfolio

Properties of the .Net Framework Inheritance

Supplier Inherits from Contact and multiple Interfaces[DeveloperInfo("Adrian Martin", Date = "9-23-2009", Title = "Supplier")] [CustomDescription("This class is custom collection class of Supplier")] [Serializable] public sealed class Supplier : Contact, IComparable, ISerializable { public string HomePage { get { return homepage; } set { if (value == null) { string fault = "You must specify a value (not null) for Homepage"; throw new ArgumentOutOfRangeException(fault); } if ((value.Length < 5) || (value.Length > 50)) { string fault = "You must provide at least 5 and no more than 50 characters for HomePage"; throw new ArgumentOutOfRangeException(fault); } homepage = value; } } public SupplierTypes Type { get; set; } public string homepage;

InterfacesICompanyContact Interfacenamespace Foundation{ interface ICompanyContact { int ID { get; set; } string CompanyName { get; set; } string ContactName { get; set; } string ContactTitle { get; set; } }}

Page 13: My Portfolio

IEnumerable

Enumeration through custom collection Must Inherit from System.Collections.IEnumerable

public IEnumerable GetTypeEnumerator(SupplierTypes supplierType) { foreach(Supplier supplier in suppliersCollection) { if(supplierType == supplier.Type) { yield return supplier; } } }