Framework Project

26
Business Framework Tier Introduction: For this project, I was responsible for developing parts of the business tier for a retail company. The product consists of two dynamic linked libraries: The Foundation class library, which consists of various interfaces and base classes for general purpose usage The AppTypes class library, which contains various entity, collection and exception classes used by the business processes The automated unit test used for testing the two assemblies enforces the compliance with the naming convention, coding convention, commenting convention, use of regions, and encapsulation convention. Audience: Third party business tier(s) that impalements the business logic for the retail company. Project Goals: Create and test two assemblies, the Foundation and the AppTypes class libraries. Compliance for both assemblies with the naming convention, coding convention, commenting convention, use of regions, and encapsulation convention. Provide adequate error handling.

description

Basic parts of the business tier for a retail company.

Transcript of Framework Project

Page 1: Framework  Project

Business Framework Tier

Introduction:

For this project, I was responsible for developing parts of the business tier for a retail company. The product consists of two dynamic linked libraries:

The Foundation class library, which consists of various interfaces and base classes for general purpose usage

The AppTypes class library, which contains various entity, collection and exception classes used by the business processes

The automated unit test used for testing the two assemblies enforces the compliance with the naming convention, coding convention, commenting convention, use of regions, and encapsulation convention.

Audience:

Third party business tier(s) that impalements the business logic for the retail company.

Project Goals:

Create and test two assemblies, the Foundation and the AppTypes class libraries. Compliance for both assemblies with the naming convention, coding convention,

commenting convention, use of regions, and encapsulation convention. Provide adequate error handling.

Page 2: Framework  Project

ICustomCollection Interface

The interface ICustomCollection for custom collections basic functionality

/// <summary>/// Provides the contract to guarantee that certain basic collection/// functionality will be available in collection classes that will be/// implementing it./// </summary>public interface ICustomCollection{ /// <summary> /// Adds an object to the Collection and returns the int value of the /// collection index of the object just added /// </summary> /// <param name="value">The object being added to the collection</param> /// <returns> /// The position that the object is found at once added to the Collection /// </returns> int Add(object value); /// <summary> /// Removes all objects from the Collection. /// </summary> void Clear(); /// <summary> /// Determines whether the collection contains the object specified in /// value. /// </summary> /// <param name="value">The object to search for</param> /// <returns>True if found</returns> bool Contains(object value); /// <summary> /// Determines the index of a specific object in the collection. /// </summary> /// <param name="value">The object to search for</param> /// <returns>True if found</returns> int IndexOf(object value); /// <summary> /// Inserts an object into the collection at the specified index. /// </summary> /// <param name="index">The position to insert the object to</param> /// <param name="value">The object to be inserted</param> void Insert(int index, object value); /// <summary> /// Removes the first occurrence of the specified object from the /// collection. /// </summary> /// <param name="value"> /// The object whose first instance will be removed (if any found) /// </param> void Remove(object value);

Page 3: Framework  Project

ICustomCollection interface continued from previous page . . .

/// <summary> /// Removes the object at the specified position. /// </summary> /// <param name="index"> /// The position in which the object will be removed at /// </param> void RemoveAt(int index); /// <summary> /// Read only property to get the number of elements currently held in /// the collection. /// </summary> int Count { get; } /// <summary> /// Copy the collection to an array of object provided in the argument. /// </summary> /// <param name="array">The array to copy the list to</param> void CopyTo(object[] array); /// <summary> /// Sorts the collection using the IComparable interface of each member /// of the collection. /// </summary> void Sort(); /// <summary> /// Sorts the collection using the supplied IComparer /// </summary> /// <param name="cmpr">The IComparer to be used when sorting</param> void Sort(System.Collections.IComparer cmpr); /// <summary> /// Retrieves or replace the object at the specified index /// </summary> /// <param name="index"> /// The position to retreive or replace the object at /// </param> /// <returns> /// Either the object retreived or modified at the specified position /// </returns> object this[int index] { get; set; }}

The interface ICustomCollection – which is one of the classes found in the Foundation class library – is provided as a contract to guarantee that certain basic collection functionality will be available in collection classes that will be implemented. Among the features of that functionality, the ability to provide a sorting comparison criteria to sort the collection with and the indexing for a direct manipulation of any item in the collection.

Page 4: Framework  Project

Foundation Class Diagram

The diagram above depicts the interfaces and base classes found in the Foundation library. The interface ICustomCollection has been expanded to show the details which are shown in the code sample.

Page 5: Framework  Project

Strongly Typed Suppliers Collection

The custom collection class Suppliers

/// <summary>/// A custom collection class. This class is representative of code written/// before the System.Collection.Generic was available. It is tipical of the/// bulk of code you would find in production today. The class will delegate/// the handing of its elements to an instance of ArrayList. The collection/// will be strongly typed, will only hold references of type Supplier, and/// will not allow duplicates (suppliers that compare as equal)./// </summary>[Serializable][DeveloperInfoAttribute("Mauro Sist", Title = "Developer", Date = "Today")][CustomDescriptionAttribute("Custom Class Suppliers")]public class Suppliers : ICustomCollection, IEnumerable{ private ArrayList suppliersCollection;

private const string typeMessage = "Type mismatch"; private const string dupeMessage = "The supplier item is already in the collection";

/// <summary> /// The default constructor which sets the collection as empty /// </summary> public Suppliers() { suppliersCollection = new ArrayList(); // starts from an empty list }

#region ICustomCollection Members

/// <summary> /// Adds an item to the collection enforcing type and uniqueness /// constraints in the argument. /// </summary> /// <param name="value">The element to be added.</param> /// <returns>The index of the element being added.</returns> public int Add(object value) { // Enforce type constraint. Supplier item = (Supplier)value; if (item == null) throw new ArgumentException(typeMessage); // Enforce uniqueness. if (suppliersCollection.Contains(item)) throw new AppTypesException(dupeMessage); // Add to the list. return suppliersCollection.Add(item); }

Page 6: Framework  Project

Suppliers class continued from previous page . . .

/// <summary> /// Clears up the collection by releasing access to all the references /// (instances still in the heap!). /// </summary> public void Clear() { suppliersCollection.Clear(); }

/// <summary> /// Determines whether an element is present in the collection enforcing /// type constraint in the argument. /// </summary> /// <param name="value">The element to search for</param> /// <returns>True if found</returns> public bool Contains(object value) { // Inspect type, first. Supplier item = (Supplier)value; if (item == null) throw new ArgumentException(typeMessage); return suppliersCollection.Contains(item); }

/// <summary> /// Gives the position of a given element in the collection enforcing /// type constraint in the argument. /// </summary> /// <param name="value">The element to search for</param> /// <returns>The index of the element, if found. Otherwise -1</returns> public int IndexOf(object value) { // inspect type, first Supplier item = (Supplier)value; if (item == null) throw new ArgumentException(typeMessage); return suppliersCollection.IndexOf(item); }

/// <summary> /// Inserts an element in a given position inside the collection /// enforcing type constraint in the argument. /// </summary> /// <param name="index"></param> /// <param name="value"></param> public void Insert(int index, object value) { // Inspect type, first. Supplier item = (Supplier)value; if (item == null) throw new ArgumentException(typeMessage); // Enforce uniqueness.

Page 7: Framework  Project

Suppliers class continued from previous page . . .

if (suppliersCollection.Contains(item)) throw new AppTypesException(dupeMessage); suppliersCollection.Insert(index, item); }

/// <summary> /// Removes a given element in the collection enforcing type constraint /// in the argument. /// </summary> /// <param name="value">The element to be removed.</param> public void Remove(object value) { // Inspect type, first. Supplier item = (Supplier)value; if (item == null) throw new ArgumentException(typeMessage); suppliersCollection.Remove(item); }

/// <summary> /// Removes the element at a given index. /// </summary> /// <param name="index">The index of the element to be removed.</param> public void RemoveAt(int index) { suppliersCollection.RemoveAt(index); }

/// <summary> /// Gives the mumber of elements held by the collection. /// </summary> public int Count { get { return suppliersCollection.Count; } }

/// <summary> /// Makes an array of object references from the collection. /// </summary> /// <param name="array">The array of object references.</param> public void CopyTo(object[] array) { suppliersCollection.CopyTo(array); }

/// <summary> /// Performs the sort on the collection using the std comparer. /// </summary> public void Sort() { suppliersCollection.Sort(); }

Page 8: Framework  Project

Suppliers class continued from previous page . . .

/// <summary> /// Performs the sort on the collection using the given comparer. /// </summary> /// <param name="cmpr">The comparer to sort the collection with</param> public void Sort(IComparer cmpr) { suppliersCollection.Sort(cmpr); }

/// <summary> /// The indexer property for the collection /// </summary> /// <param name="index"> /// The position of the element being referenced /// </param> /// <returns>The reference to the element at the given position</returns> public object this[int index] { get { return (object)suppliersCollection[index]; } set { // Inspect type, first. Supplier item = (Supplier)value; if (item == null) throw new ArgumentException(typeMessage); suppliersCollection[index] = item; } }

#endregion

#region IEnumerable Members

/// <summary> /// Provides an enumerator to iterate over the collection /// </summary> /// <returns>The enumerator to iterate the collection with</returns> public IEnumerator GetEnumerator() { return new SuppliersEnumerator(this); }

#endregion

Page 9: Framework  Project

Suppliers class continued from previous page . . .

private class SuppliersEnumerator : IEnumerator { #region IEnumerator Members

public object Current { get { try { // Get a reference through the indexer. return (object)suppliers[cursor]; } catch (IndexOutOfRangeException) { throw new InvalidOperationException( "Iterator outside the boundary"); } } }

public bool MoveNext() { // Shift, then inspect for overflow on the right. if (++cursor < suppliers.Count) return true; return false; }

public void Reset() { // Bring it bak before the first element. cursor = -1; }

#endregion

private Suppliers suppliers; private int cursor;

public SuppliersEnumerator(Suppliers suppliers) { this.suppliers = suppliers; this.cursor = -1; // before the first element } }

Page 10: Framework  Project

Suppliers class continued from previous page . . .

/// <summary> /// Provides a named enumerator to traverse the list in reverse order /// </summary> /// <returns>The reverse enumerator</returns> public IEnumerable GetReverseEnumerator() { for (int h = Count - 1; h >= 0; h--) yield return suppliersCollection[h]; }

/// <summary> /// Provides a named enumerator to reference only the elements of a given /// type in the collection. /// </summary> /// <param name="type"> /// The type of supplier the element should belong to /// </param> /// <returns>The typed enumerator</returns> public IEnumerable GetTypeEnumerator(SupplierTypes type) { IEnumerator ien = GetEnumerator(); while (ien.MoveNext()) { Supplier s = (Supplier)ien.Current; if (s.Type == type) yield return (object)s; } ien = null; // available for GC }

/// <summary> /// The global factory function to build a supplier using its default /// constructor. /// </summary> /// <returns>The default supplier</returns> public static Supplier CreateSupplier() { return new Supplier(); }

/// <summary> /// The global factory function to build a supplier using its non-default /// constructor. /// </summary> /// <param name="id">The company id</param> /// <param name="company">The company name</param> /// <param name="name">The contact name</param> /// <param name="title">The contact title</param> /// <param name="address">The address</param> /// <param name="city">The city</param> /// <param name="region">The region</param> /// <param name="code">The postal code</param>

Page 11: Framework  Project

Suppliers class continued from previous page . . .

/// <param name="country">The country prefix</param> /// <param name="phone">The phone number</param> /// <param name="fax">The fax number</param> /// <param name="home">The wheb home page address</param> /// <param name="st">The type of the supplier</param> /// <returns>The reference the instance</returns> public static Supplier CreateSupplier( int id, string company, string name, string title, string address, string city, string region, string code, string country, string phone, string fax, string home, SupplierTypes st) { return new Supplier(id, company, name, title, address, city, region, code, country, phone, fax, home, st); }

/// <summary> /// Provides serialization for this class to an IO stream /// </summary> /// <param name="suppliers">The Suppliers instance to serialize</param> /// <param name="stream">The IO stream to write to</param> public static void Serialize(Suppliers suppliers, Stream stream) { SoapFormatter formatterToStream = new SoapFormatter(); // file out the number of items to be used for deserialization formatterToStream.Serialize(stream, suppliers.Count); // file out all the items in the list foreach (Supplier s in suppliers) { formatterToStream.Serialize(stream, s); } }

/// <summary> /// Creates an instance of this class from data read from an IO stream /// </summary> /// <param name="stream">The IO stream to read data from</param> /// <returns> /// The Suppliers instance populated with data from the stream /// </returns> public static Suppliers Deserialize(Stream stream) { Suppliers sr = new Suppliers();

Page 12: Framework  Project

Suppliers class continued from previous page . . .

SoapFormatter formatterFromStream = new SoapFormatter(); int items = -1; try { items = (int)formatterFromStream.Deserialize(stream); } catch (SerializationException) { // just return an empty collection . . . return sr; } for (int j = 0; j < items; j++) { try { Supplier s = (Supplier)formatterFromStream.Deserialize(stream); sr.Add(s); } catch (SerializationException) { // returns what gotten so far . . . return sr; } } return sr; }}

The Supplier class defined in the previous pages implements the ICustomCollection (discussed earlier) and System.IEnumerable interfaces. All members of the ICustomCollectionInterface are to delegate the appropriate methods of the private member variable of class ArrayList to implement the functionality of the member. The Supplier class is strongly typed such that it will only contain instances of Supplier class. No duplicates are allowed to be added to the collection. Two Supplier instances that compare equal will be considered duplicates.A private inner class SuppliersEnumerator derived from IEnumerator is used to provide a mean to iterate over the collection. That provides the functionality required to implement the System.IEnumerable interface.Two named iterators are provided for reverse iteration over the collection and over a selected type of items in the collection.The Supplier class provides support for both serialization and deserialization. The serialization is made using the SOAP formatting.

Page 13: Framework  Project

Class Suppliers in the AppTypes project Class Diagram

Page 14: Framework  Project

Strongly Typed Products Collection

The custom collection class Products

/// <summary>/// The product class will be provided to manage a collection of Product/// instances. It utilizes the System.Collections.Generic namespace./// By virtue of implementing IList<T> where T is Product, the collection/// will be strongly typed. Additional benefit will be derived by not/// allowing duplicates and rising an event anytime the collection is/// changed./// </summary>[Serializable][DeveloperInfoAttribute("Mauro Sist", Title = "Developer", Date = "Today")][CustomDescriptionAttribute("Custom Class Products")]public class Products : IList<Product>{ /// <summary> /// The collection of Product instances /// </summary> protected List<Product> productsCollection;

/// <summary> /// The default constructor that initiantiates an empty collection /// </summary> public Products() { productsCollection = new List<Product>(); isReadOnly = false; }

/// <summary> /// The event that any listener needs to register with /// </summary> public event CollectionModifiedHandle CollectionModified;

/// <summary> /// Rises an event to notify the listeners that a modification in the /// collection occurred. /// </summary> /// <param name="args"></param> public void OnCollectionModified(ModificationEventArgs args) { // make sure there is at least one listener registered, first! if (CollectionModified == null) return; // now it is safe to rise the event CollectionModified(this, args); }

#region IList<Product> Members

Page 15: Framework  Project

Products class continued from previous page . . .

/// <summary> /// Provides the index of a given item inside the collection /// </summary> /// <param name="item">The item to look for inside the collection</param> /// <returns> /// The position of the given item inside the collection /// </returns> public int IndexOf(Product item) { return productsCollection.IndexOf(item); }

/// <summary> /// Inserts an item at a given position inside the collection enforcing /// uniqueness. /// </summary> /// <param name="index"> /// The position at which the item will be inserted /// </param> /// <param name="item">The item to be inserted</param> public void Insert(int index, Product item) { if (productsCollection.Contains(item)) throw new AppTypesException( "The product item is already in the collection."); try { productsCollection.Insert(index, item); ModificationEventArgs args = new ModificationEventArgs(item, ModificationEventStatus.successful); OnCollectionModified(args); } catch (ArgumentOutOfRangeException) { // List<T>.Insert() may throw this exception // let the listener(s) know that the modification could not be // carried out ModificationEventArgs args = new ModificationEventArgs(item, ModificationEventStatus.unsuccessful); OnCollectionModified(args); } }

/// <summary> /// Removes an item at a given position inside the collection /// </summary> /// <param name="index"> /// The position at which the removal will happen /// </param> public void RemoveAt(int index) { try

Page 16: Framework  Project

Products class continued from previous page . . .

{ productsCollection.RemoveAt(index); ModificationEventArgs args = new ModificationEventArgs(); OnCollectionModified(args); } catch (ArgumentOutOfRangeException) { ModificationEventArgs args = new ModificationEventArgs(null, ModificationEventStatus.unsuccessful); OnCollectionModified(args); } }

/// <summary> /// The indexer that allows to reference any items in the list by index /// </summary> /// <param name="index">The position of the item being referenced</param> /// <returns></returns> public Product this[int index] { get { return productsCollection[index]; } set { productsCollection[index] = value; ModificationEventArgs args = new ModificationEventArgs(value, ModificationEventStatus.successful); OnCollectionModified(args); } }

#endregion

#region ICollection<Product> Members

/// <summary> /// Adds an item to the collection avoiding duplicates /// </summary> /// <param name="item">The item to be added to the collection</param> public void Add(Product item) { if (!productsCollection.Contains(item)) { productsCollection.Add(item); ModificationEventArgs args = new ModificationEventArgs(item, ModificationEventStatus.successful); OnCollectionModified(args); } else {

Page 17: Framework  Project

Products class continued from previous page . . .

ModificationEventArgs args = new ModificationEventArgs(item, ModificationEventStatus.unsuccessful); OnCollectionModified(args); throw new AppTypesException( "The supplier item is already in the collection"); } }

/// <summary> /// Removes all the element in the collection /// </summary> public void Clear() { productsCollection.Clear(); ModificationEventArgs args = new ModificationEventArgs(); OnCollectionModified(args); }

/// <summary> /// Determines whether an element is present in the collection /// </summary> /// <param name="item">The element to search for</param> /// <returns>True if found</returns> public bool Contains(Product item) { return productsCollection.Contains(item); }

/// <summary> /// Copies the entire collection to a compatible one-dimension array /// </summary> /// <param name="array">The array to copy the collection to</param> /// <param name="arrayIndex"> /// The index of the dimension of the array (usually 0) /// </param> public void CopyTo(Product[] array, int arrayIndex) { productsCollection.CopyTo(array, arrayIndex); }

/// <summary> /// Gets the number of element in the collection /// </summary> public int Count { get { return productsCollection.Count; } }

private readonly bool isReadOnly;

/// <summary> /// Specifies if the list can be modified (defaulted to true)

Page 18: Framework  Project

Products class continued from previous page . . .

/// </summary> public bool IsReadOnly { get { return isReadOnly; } }

/// <summary> /// Removes the first occurrence of a given item from the collection /// </summary> /// <param name="item">The item to be removed</param> /// <returns> /// True if an occurrence of the specified item was found /// </returns> public bool Remove(Product item) { bool done = productsCollection.Remove(item); if (done) { ModificationEventArgs args = new ModificationEventArgs(item, ModificationEventStatus.successful); OnCollectionModified(args); } return done; }

#endregion

#region IEnumerable<Product> Members

/// <summary> /// Gets an enumerator to iterate through the collection /// </summary> /// <returns>The enumerator to iterate the collection with</returns> public IEnumerator<Product> GetEnumerator() { return productsCollection.GetEnumerator(); }

#endregion

#region IEnumerable Members

/// <summary> /// IEnumerable implementation of GetEnumerator() /// </summary> /// <returns></returns> IEnumerator IEnumerable.GetEnumerator() { // a generic enumerator can be always implicitly casted to its non- // generic version return productsCollection.GetEnumerator(); }

Page 19: Framework  Project

Products class continued from previous page . . .

#endregion

/// <summary> /// The sort using the default comparer /// </summary> public void Sort() { productsCollection.Sort(); }

/// <summary> /// The sort using a given comparer to enforce the comparison criteria /// </summary> /// <param name="comparer">The comparer to compare the item with</param> public void Sort(IComparer<Product> comparer) { productsCollection.Sort(comparer); }

/// <summary> /// The global factory function to build a product using its default /// constructor /// </summary> /// <returns> /// An instance of Product initialized with the default values /// </returns> public static Product CreateProduct() { return new Product(); }

/// <summary> /// The global factory function to build a product using its non-default /// constructor /// </summary> /// <param name="id">The product id</param> /// <param name="productName">The product name</param> /// <param name="supplierId">The supplier id</param> /// <param name="categoryId">The category id</param> /// <param name="quantityPerUnit">The quantity per unit</param> /// <param name="unitPrice">The price per unit</param> /// <param name="unitsInStock"> /// The number of units currently available in stock /// </param> /// <param name="unitsOnOrder"> /// The numer of units currently on orderT /// </param> /// <param name="reOrderLevel"> /// The number of times the unit has been issued an order on /// </param> /// <returns>

Page 20: Framework  Project

Products class continued from previous page . . .

/// An instance of Product with all the properties initialized /// </returns> public static Product CreateProduct( int id, string productName, int supplierId, int categoryId, string quantityPerUnit, decimal unitPrice, int unitsInStock, int unitsOnOrder, int reOrderLevel) { return new Product(id, productName, supplierId, categoryId, quantityPerUnit, unitPrice, unitsInStock, unitsOnOrder, reOrderLevel); }}

This class represents the counterpart of the custom collection Suppliers seen earlier in what the implementation happens through a generic list of typed objects. It derives from IList<T> where T is of class Product. Likewise the class Suppliers, the bulk of the functionality is implemented by delegating the request to a private member variable of class IList<Product> and does not allow for duplicates.A CollectionModified event is raised upon modification of the collection, either for item being added, removed or edited. This, in conjunction with a public event member variable of delegate CollectionModifiedHandle, allows listeners to be receiving messages and take the appropriate actions.The collection also allows for a specific algorithm for sorting to be provided by using the appropriate method.Instances of this class can be serialized via the standard serialization process.

Page 21: Framework  Project

Class Products in the AppTypes project Class Diagram