Friday, July 31, 2009

Provider Design Patterns in NET 2.0

Posted on/at 5:39 AM by Admin

Download ProviderDesignPattern.zip - 4.01 MB

Source Article

  • Introduction
  • What are the benefits of the article ?
  • Application Architecture
  • Application Configuration
  • Provider Implementation
  • Restoring Database
  • Debugging code
  • Conclusion
  • References

Introduction

Provider Design Pattern is a new pattern that Microsoft formalized in ASP.NET Whidbey. The pattern was officially named in the summer of 2002 when Microsoft was designing Whidbey's new Personalization feature.
Benefits of Provider

  1. No need to explicitly instantiate classes. The .NET framework will automatically manage class instantiation, including re-using classes that have already been instantiated. This will greatly improve the memory management of your application.
  2. Switching data sources is much easier. Changing the source of data for your application from the current database to any database, whether SQL Server, Oracle, XML, or other, is a simple as replacing your existing concrete (implementer) class with a new concrete (implementer) class and inheriting from your provider class. That is all. Your presentation and business logic layers remain unchanged, thereby reducing effort required to switch data sources and the amount of regression testing required thereafter.
  3. Learning the Provider Design concept will make it very easy to customize built-in .NET framework providers.

A provider implementation must derive from an abstract base class, which is used to define a contract for a particular feature.
For example, to create a Person provider for SQL, you create a new class SqlPersonProvider, which derives from PersonProvider. The base class of PersonProvider is ProviderBase . The ProviderBase class is used to mark implementers as a provider and forces the implementation of a required method and property common to all providers.
clip_image002

What are the benefits of the article ?

- Understanding the implementation of Provider Design Pattern
- Understanding the implementation of 3-tier architecture application
- Understanding the application architecture
- Naming Conventions

Note: I strongly suggest that you use the exact names that I use in this document to develop your solution for the purpose of learning this concept. Once you have tested and understand how it works, then you can integrate your own naming conventions.

Application Implementation

I developed an application, Phone Book, as desktop application to describe the provider idea.
The phone book application was developed with the use of 3 tier architecture as shown on application architecture.
Database objects like tables, fields and stored procedures are represented by object oriented classes, properties and methods on the provider infos of CompanyName library
clip_image003
The presentation layer calls the result from business logic layer and then data retrieved from database by the use of providers implemented at data access layer library.
Solution Projects [ 4 Projects]:

  1. BusinessLogicLayer : The business logic layer of the application
  2. CompanyName: it includes the global classes to all solution's projects
  3. DataAccessLayer: The data access layer of the application
  4. PhoneBookApplication: The presentation layer

clip_image005

Application Architecture

The following figure depicts the common tiers of a distributed application. This document distinguishes between business data and the business processes that use the data; the business process tier is discussed only where needed for clarification. Likewise, the presentation tier is discussed only where there are direct implications for the way data is represented, such as the way Microsoft® ASP.NET Web pages expose business data.  Read More
clip_image007
the following diagram describes the architecture of all solution's projects:
clip_image009
The following diagram, ERD, is the database design of phonebook

clip_image011

The following diagram, Use-Case diagram, describe the main functionality of the application:
clip_image013
Now, we can discuss the implementation of each project:
(1) Open Visual Studio 2005
1- Create Windows Application and name it PhoneBookApplication
2- Choose File Menu --> Add --> New Project and name it BusinessLogicLayer
3- Choose File Menu --> Add --> New Project and name it DataAccessLayer
4- Choose File Menu --> Add --> New Project and name it CompanyName CompanyName :
this project will include common libraries that are globally used in the development and shared objects among projects
so you will add reference for CompanyName library to all other applications.
ex. i created the provider info classes to be shared among the "BussinessLogicLayer" and "DataAccessLayer" projects
clip_image015
(2) Add Reference to the below DLLs for the BusinessLogicLayer and DataAccessLayer

  • System.Web
  • System.Configuration
  • CompanyName

(3) Add references of "CompanyName" and "BusinessLogicLayer" to the desktop application
clip_image017
(4) Configuaring the App.config of the "PhoneBookApplication"
clip_image019 if you look to the xml elments in app.config, we define seciongroup named "PhoneBook" and added 2 sections to it which are "Person" and "Group"

clip_image020 Collapse

<sectionGroup name="PhoneBook">

<section name="Person" type="CompanyName.PhoneBook.DataAccessLayer.SectionConfig, DataAccessLayer" />

<section name="Group" type="CompanyName.PhoneBook.DataAccessLayer.SectionConfig, DataAccessLayer" />

</sectionGroup>

then define that section group as:

clip_image020[1] Collapse

<PhoneBook>

<Person>

<providers>

<add name="SqlPerson" type="CompanyName.PhoneBook.DataAccessLayer.SqlPersonProvider, DataAccessLayer"

connectionStringName="strcon" />

<add name="OraclePerson" type="CompanyName.PhoneBook.DataAccessLayer.OraclePersonProvider, DataAccessLayer"

connectionStringName="OracleConnection" />

<add name="AccessPerson" type="CompanyName.PhoneBook.DataAccessLayer.AccessPersonProvider, DataAccessLayer"

connectionStringName="AccessConnection" />

</providers>

</Person>

<Group>

<providers>

<add name="SqlGroup" type="CompanyName.PhoneBook.DataAccessLayer.SqlGroupProvider, DataAccessLayer"

connectionStringName="strcon" />

</providers>

</Group>

</PhoneBook>

then define the connection strings for data stores of "SQL, Oracle and Access"

clip_image020[2] Collapse

<connectionStrings>

<add name="strcon" connectionString="Data Source=.;Initial Catalog=AhmedEid_PhoneBook;Integrated Security=True" />

<add name="OracleConnection" connectionString="oracle_connection_string" />

<add name="AccessConnection" connectionString="Access_connection_string" />

</connectionStrings>

person provider could retrieve data from SQL,Oracle or Access database.
Group provider could retrieve data from SQL only (5) Implementing DataAccessLayer Suppose PhoneBook is a midsize business and the PhoneBookApplicaion contains 2 major sections: - Person : profile management
- Groups : categorization of persons The following code reads all providers defined in your web.config. That is all you have to do to make providers information available to other classes.

clip_image020[3] Collapse

using System;

using System.Configuration;

namespace CompanyName.PhoneBook.DataAccessLayer

{

public class SectionConfig : ConfigurationSection

{

[ConfigurationProperty("providers")]

public ProviderSettingsCollection Providers

{

get

{

return (ProviderSettingsCollection)base["providers"];

}

}

}

}

We need to create another class to have access to the Framework provider collection and to add our new provider(s) to the provider collection.

clip_image020[4] Collapse

using System;

using System.Configuration.Provider;

namespace CompanyName.PhoneBook.DataAccessLayer

{

public class ProviderList : ProviderCollection

{

public override void Add(ProviderBase provider)

{

if (provider == null) throw new ArgumentNullException("The provider parameter cannot be null.");

base.Add(provider);

}

}

}

Create another class that will initialize the provider by the provider name.
example: initialize the Group provider for SQLGroupProvider class using provider name of "SQLGroup"

clip_image020[5] Collapse

using System;

using System.Collections.Generic;

using System.Text;

using System.Web.Configuration;

using System.Configuration;

using CompanyName.PhoneBook.DataAccessLayer;

namespace CompanyName.PhoneBook.DataAccessLayer

{

public abstract class InitMember<T>

{

public static ProviderList Providers(string _providerSectionName)

{

SectionConfig qc = (SectionConfig)ConfigurationManager.GetSection(_providerSectionName);

providerCollection = new ProviderList();

// this wl instatiate PersonProvider with the class "personimpl" which inherit it

ProvidersHelper.InstantiateProviders(qc.Providers, providerCollection, typeof(T));

providerCollection.SetReadOnly();

return providerCollection;

}

private static ProviderList providerCollection;

}

}

The class takes the provider you want to initialize, i.e PersonProvider, its class and the provider name
This enum founded on CompanyName.Globals class
clip_image022
using that class from the Instance method of PersonProvider Class:

clip_image020[6] Collapse

/// <summary>

/// This will initialize the provider and add instanse to the providers list

/// </summary>

/// <param name="_Provider"></param>

/// <returns></returns>

public static PersonProvider Instance(Globals.Providers _Provider)

{

return (DataAccessLayer.PersonProvider)DataAccessLayer.InitMember

<DataAccessLayer.PersonProvider>.Providers("PhoneBook/Person")[_Provider.ToString()];

}

This method will initialize the provider and add instance to the providers list
Now our "DataAccessLayer" project has the necessary classes for all providers to be later developed.
so we are going to develop two providers:
- PersonProvider
- GroupProvider

· Now, we create our provider model:
BaseProvider --> xxxProvider --> SQLxxxProvider xxx is the name of entity like Person, Group, ....etc Person Provider Classes:

Group Provider Classes:
clip_image026clip_image024
Let me explain the implementation of the PersonProvider and you can create GroupProvider by yourself: first we create a class named "PersonProvider.cs"

clip_image020[7] Collapse

using System;

using CompanyName.PhoneBook.Providers;

using System.Configuration.Provider;

using System.Configuration;

using System.Web.Configuration;

namespace CompanyName.PhoneBook.DataAccessLayer

{

public abstract class PersonProvider : ProviderBase

{

/// <summary>

/// This will initialize the provider and add instanse to the providers list

/// </summary>

/// <param name="_Provider"></param>

/// <returns></returns>

public static PersonProvider Instance(Globals.Providers _Provider)

{

return (DataAccessLayer.PersonProvider)DataAccessLayer.InitMember

<DataAccessLayer.PersonProvider>.Providers("PhoneBook/Person")[_Provider.ToString()];

}

/// <summary>

/// Add new person

/// </summary>

/// <param name="_info"></param>

/// <returns></returns>

public abstract bool Add(PersonInfo _info);

/// <summary>

/// Modify selected person

/// </summary>

/// <param name="_info"></param>

/// <returns></returns>

public abstract bool Modify(PersonInfo _info);

/// <summary>

/// Delete selected person

/// </summary>

/// <param name="_PersonId"></param>

/// <returns></returns>

public abstract bool Delete(int _PersonId);

/// <summary>

/// Get all personns

/// </summary>

/// <returns></returns>

public abstract PersonInfo[] Find();

/// <summary>

/// Get info of person

/// </summary>

/// <param name="_PersonId"></param>

/// <returns></returns>

public abstract PersonInfo GetInfo(int _PersonId);

/// <summary>

/// Get personns that match a given criteria

/// </summary>

/// <param name="_Searchinfo"></param>

/// <returns></returns>

public abstract PersonInfo[] Find(SearchCriteriaInfo _Searchinfo);

}

}

Instance() method : is responsible for instantiating our concrete (implementer) class (SqlGeneralProvider.cs), which has been defined within Web.config. and "PersonProvider" abstract class, which it inherits from ProviderBase and include person abstracted functions. (6)
BusinessLogicLayer
clip_image028

Note: It is a good idea to add a Helper class into your BusinessLogicLayer project. This way, you can expose some common functionality to all of your BusinessLogicLayer classes just by inheriting from this helper class.

clip_image020[8] Collapse

using System;

using System.Collections.Generic;

using System.Text;

using System.Web;

namespace CompanyName.PhoneBook.BusinessLogicLayer

{

/// <summary>

/// You can use helper to provide common info./data needed OR to massage or add more info.

/// to your data before sending it to presentation.

/// </summary>

public abstract class Helper

{

protected static string MachineName

{

get

{

return Environment.MachineName;

}

}

}

// Add more methods/properties below

}

then define the business classes for the Person and Group providers.
Person.cs

clip_image020[9] Collapse

using System;

using System.Collections.Generic;

using System.Text;

using CompanyName.PhoneBook.Providers;

using CompanyName.PhoneBook.DataAccessLayer;

namespace CompanyName.PhoneBook.BusinessLogicLayer

{

public abstract class Person : Helper

{

static PersonProvider objPersonProvider;

/// <summary>

/// Person Cnstructor

/// </summary>

//Class Constructor: will be invoked 1 time only / Appdomain

static Person()

{

objPersonProvider = PersonProvider.Instance(Globals.Providers.SqlPerson);

}

// staticed methods for person

/// <summary>

/// Add new person

/// </summary>

/// <param name="_info"></param>

/// <returns></returns>

public static bool Add(PersonInfo _info)

{

// You can use helper to provide common info./data needed OR to

// massage or add more info. to your data before sending it to

// presentation.

// Here we use helper class to get MachineName and pass it along

// with data to presentation.

return objPersonProvider.Add(_info);

}

/// <summary>

/// Modify selected person

/// </summary>

/// <param name="_info"></param>

/// <returns></returns>

public static bool Modify(PersonInfo _info)

{

return objPersonProvider.Modify(_info);

}

/// <summary>

/// Delete selected person

/// </summary>

/// <param name="_PersonId"></param>

/// <returns></returns>

public static bool Delete(int _PersonId) { return objPersonProvider.Delete(_PersonId); }

/// <summary>

/// Get all personns

/// </summary>

/// <returns></returns>

public static PersonInfo[] Find() { return objPersonProvider.Find(); }

/// <summary>

/// Get info of person

/// </summary>

/// <param name="_PersonId"></param>

/// <returns></returns>

public static PersonInfo GetInfo(int _PersonId) { return objPersonProvider.GetInfo(_PersonId); }

/// <summary>

/// Get personns that match a given criteria

/// </summary>

/// <param name="_Searchinfo"></param>

/// <returns></returns>

public static PersonInfo[] Find(SearchCriteriaInfo _Searchinfo) { return objPersonProvider.Find(_Searchinfo); }

}

}

define objPersonProvider as PersonProvider to be shared among the instances of Person class. Then initialize it on the class constructor which will be invoked for one time/ Appdomain

clip_image020[10] Collapse

Person objPerson_1 = new Person(); // on class A

Person objPerson_2 = new Person(); // on class B

Person objPerson_3 = new Person(); // on class C

//Class Constructor: will be invoked 1 time only / Appdomain

static Person()

{

objPersonProvider = PersonProvider.Instance(Globals.Providers.SqlPerson);

}

The objPersonProvider will be initialized with the objPerson_1 constructor only on the class A, then other instances like objPerson_2 or objPerson_3 will use the static object objPersonProvider. you can add you business logic to every method before calling the data access provider as

clip_image020[11] Collapse

public static bool Add(PersonInfo _info)

{

// Here: you can add you business logic to every method before calling the data access provider

return objPersonProvider.Add(_info);

}

PhoneBook Application

The presentation layer as desktop application for implementing the business logic to the client. <image31>
How to use the BL layer from the presentation layer ? sample code

clip_image020[12] Collapse

// build the search criteria

SearchCriteriaInfo objSearchInfo = new SearchCriteriaInfo();

objSearchInfo.FilterNameBy = (Globals.FilterNameBy)this.cboName.SelectedValue;

objSearchInfo.GroupId = (int)cboGroup.SelectedValue;

objSearchInfo.Name = txtName.Text.Trim();

if(chkFrom.Checked)

objSearchInfo.FromDate = datefrom.Value;

if(chkTo.Checked)

objSearchInfo.ToDate = dateto.Value;

objSearchInfo.SortBy = (rdoasc.Checked) ? Globals.SortBy.Asc : Globals.SortBy.Desc;

objSearchInfo.SortByBirthDate = chkbirthdate.Checked; ;

objSearchInfo.SortByGroup = chkGroup.Checked;

objSearchInfo.SortByName = chkName.Checked;

objSearchInfo.SortByTele = chkTele.Checked;

objSearchInfo.TeleNumber = txtTeleNumber.Text.Trim();

objSearchInfo.TelephoneType = (Globals.TelephoneTypes)this.cboTeleTypes.SelectedValue;

// get result from bus logic layer

PersonInfo[] objresult = Person.Find(objSearchInfo);

clip_image030
clip_image032
How to save and retrieve image from database ?Save to database:
save the image from the picturebox to MemoryStream and then save it on database as Byte[]

clip_image020[13] Collapse

// prapare the image

if (null != imgperson.Image) // picturebox control

{

MemoryStream stream = new MemoryStream();

imgperson.Image.Save(stream, System.Drawing.Imaging.ImageFormat.Jpeg);

info.Image = stream.ToArray();

}

Retrieve from database:

clip_image020[14] Collapse

// display the image

byte[] PImage = info.Image;

if (null != PImage)

{

MemoryStream stream = new MemoryStream(PImage);

imgperson.Image = Image.FromStream(stream);

}

clip_image034

Restoring Database on SQL Server 2005

Attach the database AhmedEid_PhoneBook.mdf from the directory DataBase on the root directory to the SQL Server Engine.

Debugging Scenario

Let us debug the advanced search button code to retrieve results with criteria from the client
the following scenario will lead you to understand the Provider implementation

make breakpoints as the following
1- AdvancedSearch form class ( presentation layer )
clip_image036
2- Person class of BusinessLogicLayer ( BLL layer )
clip_image038
3- PersonProvider Class of DataAccessLayer ( DAL layer )
clip_image040
4- InittMember<T> class of DataAccessLayer ( DAL layer )
clip_image042
the above code will provide and add the SqlPersonProvider class to the providers list to be available for any usage.
clip_image044
5- SqlGroupProvider class of DataAccesslayer ( DAL layer )
clip_image046

Note: After debugging the code for 1st time , the providers (PersonProvider and groupProvider) will be added to the System.Configuration.Provider.ProviderCollection and for 2nd time the results will be retrieved without instantiating the classes again.
clip_image048
References
- http://msdn.microsoft.com/en-us/library/ms972319.aspx
- http://msdn.microsoft.com/en-us/library/ms972370.aspx
- http://msdn.microsoft.com/en-us/library/ms978496.aspx
- http://en.wikipedia.org/wiki/Design_Patterns
- http://www.c-sharpcorner.com/UploadFile/webmaster3/ProviderPattern12242007184126PM/ProviderPattern.aspx

Top of Form

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

Ahmad Eid Salim

clip_image049

Member

 

Bottom of Form

SQL Server 2005 - Merge Replication Step by Step Procedure

Posted on/at 5:29 AM by Admin

Introduction

Replication is a set of technologies for copying and distributing data and database objects from one database to another and then synchronizing between databases to maintain consistency. Using replication, you can distribute data to different locations and to remote or mobile users over local and wide area networks, dial-up connections, wireless connections, and the Internet.

Replication is the process of sharing data between databases in different locations. Using replication, we can create copies of the database and share the copy with different users so that they can make changes to their local copy of database and later synchronize the changes to the source database.

Terminologies before getting started:

Microsoft SQL Server 2000 supports the following types of replication

Publisher is a server that makes the data available for subscription to other servers. In addition to that, publisher also identifies what data has changed at the subscriber during the synchronizing process. Publisher contains publication(s).

Subscriber is a server that receives and maintains the published data. Modifications to the data at subscriber can be propagated back to the publisher.

Distributor is the server that manages the flow of data through the replication system. Two types of distributors are present, one is remote distributor and the other one local distributor. Remote distributor is separate from publisher and is configured as distributor for replication. Local distributor is a server that is configured as publisher and distributor.

Agents are the processes that are responsible for copying and distributing data between publisher and subscriber. There are different types of agents supporting different types of replication.

Snapshot Agent is an executable file that prepares snapshot files containing schema and data of published tables and database objects, stores the files in the snapshot folder, and records synchronization jobs in the distribution database.

An article can be any database object, like Tables (Column filtered or Row filtered), Views, Indexed views, Stored Procedures, and User defined functions.

Publication is a collection of articles.

Subscription is a request for copy of data or database objects to be replicated.

clip_image002

Replication Types

Microsoft SQL Server 2005 supports the following types of replication:

  • Snapshot Replication
  • Transactional Replication
  • Merge Replication

Snapshot Replication

  • Snapshot replication is also known as static replication. Snapshot replication copies and distributes data and database objects exactly as they appear at the current moment in time.
  • Subscribers are updated with complete modified data and not by individual transactions, and are not continuous in nature.
  • This type is mostly used when the amount of data to be replicated is small and data/DB objects are static or does not change frequently.

Transactional Replication

  • Transactional replication is also known as dynamic replication. In transactional replication, modifications to the publication at the publisher are propagated to the subscriber incrementally.
  • Publisher and the subscriber are always in synchronization and should always be connected.
  • This type is mostly used when subscribers always need the latest data for processing.

Merge replication

It allows making autonomous changes to replicated data on the Publisher and on the Subscriber. With merge replication, SQL Server captures all incremental data changes in the source and in the target databases, and reconciles conflicts according to rules you configure or using a custom resolver you create. Merge replication is best used when you want to support autonomous changes on the replicated data on the Publisher and on the Subscriber.

Replication agents involved in merge replication are snapshot agent and merge agent.

Implement merge replication if, changes are made constantly at the publisher and subscribing servers, and must be merged in the end.

By default, the publisher wins all conflicts that it has with subscribers because it has the highest priority. Conflict resolver can be customized

Before starting the replication process:

assume that we have 2 server:

  • EGYPT-AEID: is the publisher server ( contains HRatPublisher )
  • SPS: is the subscriber server ( contains HRatSubscriber ) use SQL server Authentication mode for login

on the publisher database i created table: Employees with fields of (ID, Name, Salary) to replicate its data to the subscriber server.

i will use publisher as subscriber also

Note: Check that SQL Server Agent is running on the publisher and the subscriber

Steps:

  1. Open SQL Server Management Studio and login with SQL Server Authentication to configure Publishing, Subscribers, and Distribution

clip_image004

a- Configure the appropriate server as publisher or distributor.

clip_image006

b- Enable the appropriate database for merge replication

clip_image008

2- Create new local publication from DB-Server --> Replication --> Local Publications --> Right Click --> New Pub

clip_image009

then choose the database that contains the data or objects you want to replicate

clip_image011

then choose the replication type and then specify the SQL server versions that will be used by subscribers to that publication like SQL Server 2005, SQL mobile Edition, SQL for Win CE ....etc

clip_image013

after that manage the replication articles, data and db objects, by choosing objects to be replicated

Note: you can manage the replication properties for selected objects

clip_image014

Then add filters to published tables to optimize performance and then configure the snapshot agent

clip_image015

clip_image017

and configure the security for snapshot agent

clip_image019

finally rename the publication and click finish

clip_image021

3- create a new subscription for the created "MyPublication01" Publication by right click on MyPublication01 --> New Subscription

that to configure the "Merge Agent" for replication on the subscriber database

clip_image022

clip_image023

then choose one or more subscriber databases. you can add new SQL Server subscribers

clip_image025

then specify the Merge Agent security as mentioned above on "Agent Snapshot"

and so specify the synchronization schedule for each agent.

Schedules:

  • Run Continuously: add schedule times to be auto run continuously
  • Run on demand only: manually run the synchronization

clip_image027

and then next up to final step, then click finish

you can check the errors from "Replication Monitor" by right click on Local Replication --> Launch Replication Monitor

Advantages in Replication:

Users can avail the following advantages by using replication process:

  • Users working in different geographic locations can work with their local copy of data thus allowing greater autonomy.
  • Database replication can also supplement your disaster-recovery plans by duplicating the data from a local database server to a remote database server. If the primary server fails, your applications can switch to the replicated copy of the data and continue operations.
  • You can automatically back up a database by keeping a replica on a different computer. Unlike traditional backup methods that prevent users from getting access to a database during backup, replication allows you to continue making changes online.
  • You can replicate a database on additional network servers and reassign users to balance the loads across those servers. You can also give users who need constant access to a database their own replica, thereby reducing the total network traffic.
  • Database-replication logs the selected database transactions to a set of internal replication-management tables, which can then be synchronized to the source database. Database replication is different from file replication, which essentially copies files.

Replication Performance Tuning Tips:

  • By distributing partitions of data to different Subscribers.
  • When running SQL Server replication on a dedicated server, consider setting the minimum memory amount for SQL Server to use from the default value of 0 to a value closer to what SQL Server normally uses.
  • Don’t publish more data than you need. Try to use Row filter and Column filter options wherever possible as explained above.
  • Avoid creating triggers on tables that contain subscribed data.
  • Applications that are updated frequently are not good candidates for database replication.
  • For best performance, avoid replicating columns in your publications that include TEXT, NTEXT or IMAGE data types.

Source

About Me

Developers house is a blog for posting technical articles in different technology like Microsft, Java, Oracle ..etc Microsoft technology includes c#,VB.net,ASP.net,Ajax,SilverLight,TFS,VS.NET 2003,2005,2008,2010 , SQL Server 2000, 2005 , Expression Blend , ...etc I hope it is helpful for all of you and if you are interested to post articles on it, only send me at ahmad.eed@gmail.com