My Portfolio


Published on

A portfolio of my library project and some .Net concepts

Published in: Technology
  • Be the first to comment

  • Be the first to like this

No Downloads
Total views
On SlideShare
From Embeds
Number of Embeds
Embeds 0
No embeds

No notes for slide

My Portfolio

  1. 1. Windows Application<br />Library <br />Introduction:<br /> 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. <br />Audience:<br />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.<br />Project Goals:<br /> • 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<br />• Design the Presentation, Business and Data Access tiers<br />• Develop code that is easily maintainable. <br />• Provide validation for all required fields (see details below). <br />• Provide adequate error handling. <br />• Produce a user interface that is intuitive, requiring minimal training for users while minimizing resource utilization. <br />• Produce a user interface that is intuitive, requiring minimal training for users while minimizing resource utilization. <br />Database Manipulation (n-tier interaction)<br />Adding Adult <br /> private void aAButton_Click(object sender, EventArgs e)<br /> {<br /> aApicturebox.Visible = false;<br /> if (aAfirstName.Text != string.Empty && aAlastName.Text != string.Empty<br /> && aAStreet.Text != string.Empty && aACity.Text != string.Empty &&<br /> aAstate.Text != string.Empty && aAZip.Text != string.Empty)<br /> {<br /> BusinessLayer biz = new BusinessLayer(); // Create Business object for commincation to <br />Library Access Data Layer.<br /> AdultMember Adult = new AdultMember(); // AdultMember is type declared in LibraryEntities. This allows population<br /> Adult.FirstName = aAfirstName.Text; // of AdultMember properties.<br /> Adult.LastName = aAlastName.Text;<br /> Adult.Street = aAStreet.Text;<br /> Adult.City = aACity.Text;<br /> Adult.State = aAstate.Text;<br /> Adult.ZipCode = aAZip.Text;<br /> toolStripContainer1.Text = biz.AddAdult(Adult);<br /> if (" Adult member added" == toolStripContainer1.Text) // Notify in various ways of success and new Member ID<br /> { <br /> aAsuccess.Visible = true;<br /> aAsuccessStatus.Text = String.Format(Adult.FirstName + " successfully added!" );<br /> aAsuccessID.Text = String.Format(" Your member ID is now " + Adult.MemberID.ToString());<br /> toolStripStatusLabel1.Text = " Adult successfully added" ;<br /> }<br /> else <br /> {<br /> MessageBox.Show(" Member could not be added to database. Please contact program Administator" );<br /> }<br /> }<br /> else // The required information was not provided by the user<br /> {<br /> MessageBox.Show(" Please fill out required information to add Adult" , " Adult Not Added" , MessageBoxButtons.OK);<br /> }<br /> <br /> }<br />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.<br />Verifying Alpha Characters for Validation<br />private bool VerifyCharacters(Control control)<br /> {<br /> Match nonchars = Regex.Match(control.Text, @" [^A-Za-z]" );<br /> // Does a match to make sure they aren't numbers<br /> if (nonchars.Success)<br /> {<br /> errorProvider1.SetError(control, " Must use alphabetical characters" );<br /> return true;<br /> <br /> }<br /> else { return false; }<br /> }<br />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. <br />Auto Correct<br />private string AutoCaseCorrect(string name)<br /> {<br /> if (name != string.Empty) <br /> {<br /> string temp = name.Substring(0, 1); // Grabs first letter of text string<br /> return temp.ToUpper() + name.Remove(0, 1).ToLower(); //Concats first letter UpperCase and the rest letters LowerCase<br /> //then returns result<br /> }<br /> return string.Empty; <br /> }<br />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.<br />Adding Adult through Business Layer after Validation<br /> /// <summary><br /> /// Adds an Adult to the Library Data Access layer. Accepts an AdultMember<br /> /// object as parameter<br /> /// </summary><br /> /// <param name=" member" ></param><br /> /// <returns></returns><br /> public string AddAdult(AdultMember member)<br /> { <br /> LibraryDataAccess lda = new LibraryDataAccess();<br /> try<br /> {<br /> lda.AddMember(member);<br /> return " Adult member added" ;<br /> }<br /> catch<br /> {<br /> return ErrorCode.AddAdultFailed.ToString();<br /> }<br /> }<br />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.<br />Retrieving Data from Library Database Access Layer and Populating Form<br /> private void historyInfoButton_Click(object sender, EventArgs e)<br /> {<br /> if (historyMemberID.Text != string.Empty)<br /> {<br /> short memberId = short.Parse(historyMemberID.Text);<br /> <br /> Member mymember = new Member(); //Member object to display in form<br /> BusinessLayer b1 = new BusinessLayer(); //BusinessLayer object to get Items on Loan from<br /> ItemsDataSet ids = b1.GetItemsOnLoan(memberId); //Library Database and member information to <br /> //populate DataGrid<br /> mymember = b1.GetInformation(memberId);<br /> if (mymember != null)<br /> {<br /> historyDataGrid.DataSource = ids.Items; //Display Items in Grid and Member Information in designated groupbox<br /> historygroupBox.Visible = true;<br /> historyDataGrid.Visible = true;<br /> historyFirstName.Text = mymember.FirstName;<br /> historyLastName.Text = mymember.LastName;<br /> historyStreet.Text = mymember.Street;<br /> historyCity.Text = mymember.City;<br /> historyZipcode.Text = mymember.ZipCode.ToString();<br /> historyState.Text = mymember.State;<br /> historyExpiration.Text = mymember.ExpirationDate.ToString();<br /> if (mymember.ExpirationDate < DateTime.Today)<br /> chkoutCardExpired.Visible = true;<br /> }<br /> else<br /> {<br /> errorProvider1.SetError(chkoutMemberID, " Must clear form before making another inquiry" );<br /> }<br /> }<br /> else { historygroupBox.Visible = false; }<br /> }<br />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.<br />Custom Stored Procedure in SSMS used to Check Out an Item<br />USE [library]<br />GO<br />/****** Object:  StoredProcedure [dbo].[CheckOut]    Script Date: 10/28/2009 12:43:19 ******/<br />SET ANSI_NULLS ON<br />GO<br />SET QUOTED_IDENTIFIER ON<br />GO<br />/*<br />CheckOut : Checks out a book<br />written: Adrian Martin<br />Date 10/27/09<br />Parameters:<br />        ISBN,<br />        Copy_no,<br />        Member_no<br /> <br />State Values:<br />      'ISBN cannot be null value'               1<br />      'Copy_no cannot be null value'            2<br />      'Member_no cannot be null value'          3<br />      'Item does not exist'                           4 <br />      'Item is already on loan'                       5<br />      'Item was not able to be ckecked in'      6<br />*/<br /> <br /> <br />CREATE PROC  [dbo].[CheckOut]<br />@ISBN       char(20)                = null,<br />@Copy_no    smallint              = null,<br />@Member_no  smallint<br /> <br />AS<br /> <br />BEGIN TRY<br />--Validation<br />IF @ISBN is null<br />      BEGIN<br />            PRINT('ISBN cannot be a null value')<br />            RAISERROR('ISBN cannot be a null value', 14, 1)<br />      END<br />IF @Copy_no is NULL<br />      BEGIN<br />            PRINT('Copy_no cannot be a null value')<br />            RAISERROR('Copy_no cannot be a null value',14, 2)<br />      END<br />IF @Member_no is NULL<br />      BEGIN<br />            PRINT('Member_no cannot be a null value')<br />            RAISERROR('Member_no cannot be a null value',14, 3)<br />      END<br />                  <br />--Validate if item exist in library<br />IF NOT EXISTS   -<br />   (<br />                        Select isbn,copy_no FROM copy<br />                        WHERE copy.isbn = @ISBN<br />                        AND copy.copy_no = @Copy_no<br />                      )  <br />      BEGIN<br />                  PRINT('Item does not exist')<br />                  RAISERROR('Item does not exist',14,4)<br />      END<br />--Validate item isn’t already on loan<br />IF EXISTS  <br /> (<br />                  Select isbn,copy_no,loanable FROM [Item Information]<br />                  WHERE [Item Information].isbn = @ISBN<br />                  AND  [Item Information].copy_no = @Copy_no<br />                  AND [Item Information].on_loan = 'Y'<br />                  )<br />      BEGIN<br />            PRINT('Item is already on loan')<br />            RAISERROR('Item is already on loan', 14, 5)<br />      END<br />--DO WORK<br />ELSE<br />      BEGIN<br /> <br />DECLARE @Out_Date datetime,--<br />  @Due_date datetime,<br />  @Title_no int<br />            <br />SET @Out_Date = GETDATE()--Check out Date equals Today<br />SET   @Due_date = DATEADD(WEEK,2,GETDATE())--Due Date equals 2 weeks from Today<br />SET @Title_no = <br />                  (<br />                        SELECT title_no FROM [Item Information]<br />                        WHERE [Item Information].isbn = @ISBN<br />                        AND [Item Information].copy_no = @Copy_no<br />                  )<br />            <br />      <br />            BEGIN TRANSACTION<br /> <br /> --Insert Check Out Item into the loan table<br />            INSERT loan<br />            (<br />                  ISBN,<br />                  copy_no,<br />                  title_no,<br />                  member_no,<br />                  out_date,<br />                  due_date<br />            )<br />            <br />            VALUES<br />            (<br />                  @ISBN,<br />                  @Copy_no,<br />                  @Title_no,<br />                  @Member_no,<br />                  @Out_Date,<br />                  @Due_date<br />            )<br /> <br />--Update copy tables on_loan to Y<br />    DECLARE @OnLoan varchar = 'Y'<br />      UPDATE copy<br />      SET on_loan = @OnLoan<br />      WHERE copy.isbn = @ISBN<br />      AND copy.copy_no = @Copy_no<br />            <br />            COMMIT TRANSACTION<br />      END<br />END TRY<br />BEGIN CATCH<br /> <br />      IF @@TRANCOUNT <> 0--If was in process of transaction rollback and raise error<br />            BEGIN<br />                  ROLLBACK TRANSACTION<br />                  PRINT('Item was not able to be checked out')<br />                <br />  RAISERROR('Item was not able to be ckecked out',14,6)<br />            END<br />      print 'starting catch'<br />      --local vars<br />      DECLARE @ErrorMessage NVARCHAR(4000);<br />      DECLARE @ErrorSeverity INT;<br />      DECLARE @ErrorState INT;<br />      --populate vars<br />      SELECT @ErrorMessage = ERROR_MESSAGE(), @ErrorSeverity = ERROR_SEVERITY(), <br />                  @ErrorState = ERROR_STATE();<br />      -- rethrow goes to fron end c#<br />      RAISERROR (@ErrorMessage, @ErrorSeverity, @ErrorState);<br />      RETURN<br /> <br />END CATCH<br />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.<br />/// <summary><br /> /// Check out item checks out an item given memberID, isbn, and copynumber as parameters<br /> /// </summary><br /> /// <param name=" memberid" ></param><br /> /// <param name=" isbn" ></param><br /> /// <param name=" copyno" ></param><br /> public void CheckOutItem(short memberid,Int32 isbn, short copyno)<br /> {<br /> var ldc = new LibraryDataContext();<br /> try<br /> {<br /> ldc.CheckOut(isbn, copyno, memberid);<br /> }<br /> catch<br /> {<br /> throw new LibraryException(ErrorCode.CheckOutFailed, " Check Out Failed" );<br /> }<br /> }<br />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.<br />Library Final Product<br />Properties of the .Net Framework <br />Inheritance<br />Supplier Inherits from Contact and multiple Interfaces<br />[DeveloperInfo(" Adrian Martin" , Date = " 9-23-2009" , Title = " Supplier" )]<br /> [CustomDescription(" This class is custom collection class of Supplier" )]<br /> [Serializable]<br /> public sealed class Supplier : Contact, IComparable, ISerializable<br /> {<br /> <br /> public string HomePage<br /> {<br /> get<br /> {<br /> return homepage;<br /> }<br /> set<br /> {<br /> if (value == null)<br /> {<br /> string fault = " You must specify a value (not null) for Homepage" ;<br /> throw new ArgumentOutOfRangeException(fault);<br /> }<br /> if ((value.Length < 5) || (value.Length > 50))<br /> {<br /> string fault = " You must provide at least 5 and no more than 50 characters for HomePage" ;<br /> throw new ArgumentOutOfRangeException(fault);<br /> }<br /> homepage = value;<br /> }<br /> }<br /> public SupplierTypes Type { get; set; }<br /> public string homepage;<br />Interfaces<br />ICompanyContact Interface<br />namespace Foundation<br />{<br /> <br /> interface ICompanyContact<br /> {<br /> int ID { get; set; }<br /> string CompanyName { get; set; }<br /> string ContactName { get; set; }<br /> string ContactTitle { get; set; } <br /> }<br />}<br />IEnumerable<br />Enumeration through custom collection<br /><ul><li>Must Inherit from System.Collections.IEnumerable</li></ul> public IEnumerable GetTypeEnumerator(SupplierTypes supplierType)<br /> {<br /> foreach(Supplier supplier in suppliersCollection)<br /> {<br /> if(supplierType == supplier.Type)<br /> {<br /> yield return supplier;<br /> }<br /> }<br /> }<br />