Friday, November 16, 2012

Observer Design Pattern using Delegates/events

Today I want to discuss with you how to implement Observer design pattern using delegate and event in asp.net /c#.

Observer Pattern

The observer pattern is a software design pattern in which an object, called the subject, maintains a list of its dependents, called observers, and notifies them automatically of any state changes, usually by calling one of their methods. It is mainly used to implement distributed event handling systems. The Observer pattern is also a key part in the familiar Model View Controller (MVC) architectural pattern.(wikipedia).

UML class diagram of Observer pattern(wikipedia)





The Observer Pattern describes the dependence relationship between one object (observable) to many objects (observers). It's also called Model/View, Dependents, or Distributor/Listener pattern.This article introduces an implementation when we can use the Observer pattern to keep all observer objects updated after things have changed.

Case project

In this case, patient is an ObservableObject that needs to send out the notification when the hospital updates his/her physical status. The hospital will determine who will be notified when the patient status is updated.

In our scenario,  patient (observable object) admitted in hospital and they are observed by multiple observer (relative and doctor). Each observer get multiple time physical updated status from hospital daily.


Sample Class diagram for our case project

Code:
IObservable.cs


namespace ObserverDesignPatternLib
{
    public delegate void NotifyObserver(string key);
    internal interface IObservable
    {
        void AddObserver(NotifyObserver ob);
        void RemoveObserver(NotifyObserver ob);
        void Notify(string observerName);
    }
}
----------------------------------------------
ObservableObject.cs


namespace ObserverDesignPatternLib
{
    public class ObservableObject:IObservable
    {
        public event NotifyObserver NotifyObserverEvent;

        public void AddObserver(NotifyObserver ob)
        {
            NotifyObserverEvent += ob;
        }

        public void RemoveObserver(NotifyObserver ob)
        {
            NotifyObserverEvent -= ob;
        }

        public void Notify(string observerName)
        {
            if (NotifyObserverEvent != null)
            {
                NotifyObserverEvent(observerName);
            }
        }
    }
}


-----------------------------------------------

Status.cs

public class Status
    {
        public string Description { get; set; }
        public DateTime UpdatedOn { get; set; }

        public Status(string notes)
        {
            Description = notes;
            UpdatedOn = DateTime.Now;
        }
    }
----------------------------------------

Patient .cs

public class Patient : ObservableObject
    {
        public string Name { get; set; }
        public int Age { get; set; }
        public string Address { get; set; }

        private Status _patientStatus;

        public Status PatientStatus
        {
            get { return _patientStatus; }
            set
            {
                _patientStatus = value;
                Notify(this.Name);
            }
        }
    }
----------------------------------------

Doctor.cs 

public class Doctor
    {
        private Dictionary _patients = new Dictionary();

        public Dictionary Patients
        {
            get { return _patients; }
            set { _patients = value; }
        }


        public void RecivePatientStatus(string paitientName)
        {
            Console.WriteLine("Doctor received {0}'s new status:\nAge: {1}\nAddress:{2}\nUpdates on: {3}\nDescription: {4} \n\n",
                Patients[paitientName].Name,
                Patients[paitientName].Age,
                Patients[paitientName].Address,
                Patients[paitientName].PatientStatus.UpdatedOn,
                Patients[paitientName].PatientStatus.Description);
        }
    }
---------------------------------------------

Relative.cs

public class Relative
    {
        private Dictionary _patients = new Dictionary();

        public Dictionary Patients
        {
            get { return _patients; }
            set { _patients = value; }
        }

        public void PatientStatusUpdate(string key)
        {
            Console.WriteLine("Relative received {0}'s new status:\nAge: {1}\nAddress:{2}\nUpdates on: {3}\nDescription: {4} \n\n",
                Patients[key].Name,
                Patients[key].Age,
                Patients[key].Address,
                Patients[key].PatientStatus.UpdatedOn,
                Patients[key].PatientStatus.Description);
        }
    }
------------------------------------------------
Progarm.cs



class Program
    {
        static void Main(string[] args)
        {
            //Two Patients been created
            var patientFever = new Patient();
            var patientDiarhoea = new Patient();

            patientFever.Name = "Al Amin";
            patientFever.Age = 15;
            patientFever.Address = "Gulshan,Dhaka";
         
            patientDiarhoea.Name = "Abdul Gaffar";
            patientDiarhoea.Age = 22;
            patientDiarhoea.Address = "Mehedibag,Chittagong.";

            //Relative object created for each patient
            var relativeFever = new Relative();
            relativeFever.Patients.Add(patientFever.Name, patientFever);

            var relativeDiarhoea = new Relative();
            relativeDiarhoea.Patients.Add(patientDiarhoea.Name, patientDiarhoea);

            //one doctor object created
            //this doctor is hospital's duty doctor, he is notified patient status time to time
            var doctor = new Doctor();
            doctor.Patients.Add(patientFever.Name, patientFever);
            doctor.Patients.Add(patientDiarhoea.Name, patientDiarhoea);


            //hospital also send status to the relatives.
            patientFever.AddObserver(new NotifyObserver(relativeFever.PatientStatusUpdate));
            patientDiarhoea.AddObserver(new NotifyObserver(relativeDiarhoea.PatientStatusUpdate));

            //Update status for both Patients. relatives will receive the status at the same time
            patientFever.PatientStatus = new Status(String.Format("{0} is feeling bed.", patientFever.Name));
            patientDiarhoea.PatientStatus = new Status(String.Format("{0} is ", patientDiarhoea.Name));

            //Updates the status after 2 secs
            Thread.Sleep(2000);

            //after 5 secs, patientDiarhoea doesn't feel well. need to get doctor involved
            patientFever.AddObserver(new NotifyObserver(doctor.RecivePatientStatus));
            patientDiarhoea.AddObserver(new NotifyObserver(doctor.RecivePatientStatus));

            //update two Patients' status.
            //relatives will recive their Patients status
            //Doctor start reciving patient's status
            patientFever.PatientStatus = new Status(String.Format("{0} is feel out of sort. Temparature : 102 F", patientFever.Name));
            patientDiarhoea.PatientStatus = new Status(String.Format("{0} is sick due to in digest.", patientDiarhoea.Name));

            //Updates the status after 3 secs
            Thread.Sleep(3000);

            //update two Patients' status
            patientFever.PatientStatus = new Status(String.Format("{0} is not feel better. Still Temparature : 100 F", patientFever.Name));
            patientDiarhoea.PatientStatus = new Status(String.Format("{0} is back to normal but weak.", patientDiarhoea.Name));


            //Updates the status after 3 secs
            Thread.Sleep(3000);
                     
            //since patient is become better. hospital's unsubscribe the doctor's observation
            patientDiarhoea.RemoveObserver(new NotifyObserver(doctor.RecivePatientStatus));

            //update two Patients' status
            patientFever.PatientStatus = new Status(String.Format("{0} is now back to normal.", patientFever.Name));
            patientDiarhoea.PatientStatus = new Status(String.Format("{0} is recover weakness.", patientDiarhoea.Name));

            Console.WriteLine("Patients regular status report.");
            Console.Read();
        }
    }

Final output



Thursday, November 15, 2012

A Custom Attribute based approach to write summary on business object

Last day, I have got a mail from a junior developer he needs some help about custom attributes. He has no previous experience about it. I have delivered his some speech or send some link for study. Today I have made an example for him, so that he can understand its usage very easily. Now this also share with you it may also help other friends.


using System;
using System.Collections.Generic;
using System.Reflection;

namespace CustomAttributes
{
   //First custom attribute class

 // The AuthorAttribute class is a user-defined custom attribute class.
 // It can be applied to any declaration including
 //  - types (struct, class, enum, delegate)
 //  - members (methods, fields, events, properties, indexers)
 // It can be use multiple times on any object.

       [AttributeUsage(AttributeTargets.All, AllowMultiple = true,Inherited = false)]
        public class AuthorAttribute : Attribute
        {
            public AuthorAttribute(string name,string date)
            {
                this.name = name;
                this.date = date;
            }

            protected String name;
            public String Name
            {
                get { return name; }
            }

            protected String date;
            public String Date
            {
                get { return date; }
            }
       
            protected double version;
            public double Version
            {
                get;
                set;
            }

            protected String comments;
            public String Comments
            {
                get;
                set;
            }

            public override string ToString()
            {
                string value = "Author : " + Name + Environment.NewLine; ;
                value += "Date : " + Date+Environment.NewLine;
                value += "Comments : " + Comments + Environment.NewLine;
                if (Math.Abs(version - 0) > 0.0)
                {
                    value += " Version : " + Version.ToString()+Environment.NewLine;
                }
                return value;
            }
        }

 //Second custom attribute class

// The IsTested class is a user-defined custom attribute class.
// It can be applied to any declaration including
//  - types (struct, class, enum, delegate)
//  - members (methods, fields, events, properties, indexers)
// It is used with no arguments.

    public class IsTestedAttribute : Attribute
    {
        public override string ToString()
        {
            return "Is Tested";
        }
    }

    //attaching Author attribute to our TestClass
        [Author("Ahsan murshed", "19-02-2012", Comments = "Create a new method TestMethod()", Version = 0.5)]
        [Author("Kamrul hasan", "19-02-2012", Comments = "Update TestMethod()", Version = 1.0)]
        public class InsertClass
        {
            //attaching Author attribute to our InsertMethod
            [Author("Ahsan murshed", "17-01-2011", Comments = "This InsertMethod() used for insert comments", Version = 1.0),IsTested()]
            public void InsertMethod()
            {
            }

            [Author("Ahsan murshed", "17-01-2011", Comments = "This DeleteMethod() used for delete comments", Version = 1.0)]
            public void DeleteMethod()
            {
            }   

            //attaching Author attribute to our AnyInt Field
            [Author("Ahsan murshed", "17-01-2011", Comments = "This is TestField comments", Version = 1.0)]
            public int TestField;
        }

    [Author("Ahsan murshed", "17-01-2011", Comments = "This is UpdateClass comments", Version = 1.0)]
    public class UpdateClass
    {
        [Author("Shahidul alam", "19-01-2012", Comments = "Add this UpdateMethod() method for update comments", Version = 1.0)]
        public void UpdateMethod()
        {
        }
    }

    public class AuthorTest
    {
        private static void WriteAttributes(MemberInfo member)
        {
            Console.WriteLine("Attributes for : " + member.Name);
            foreach (object attribute in member.GetCustomAttributes(true))
            {
                Console.WriteLine(attribute);
            }
        }

        //This is the main class
        public static void Main()
        {
            //Get the InsertClass attribute information
            Type type = typeof(InsertClass);
            WriteAttributes(type);
            FindMethodandFieldsAttributes(type);
       
           //Get the UpdateClass attribute information
            type = typeof(UpdateClass);
            WriteAttributes(type);
            FindMethodandFieldsAttributes(type);
         
            Console.ReadLine();
        }

     
        private static bool IsMemberTested(MemberInfo member)
        {
            foreach (object attribute in member.GetCustomAttributes(true))
            {
                if (attribute is IsTestedAttribute)
                {
                    return true;
                }
            }
            return false;
        }

         private static void FindMethodandFieldsAttributes(Type type)
         {
             AuthorAttribute authorAttributeAttr;
         
             //Finding Class level custom Attributes
             foreach (MethodInfo method in type.GetMethods())
             {
                 foreach (Attribute attr in method.GetCustomAttributes(true))
                 {
                     authorAttributeAttr = attr as AuthorAttribute;
                     if (null != authorAttributeAttr)
                     {
                         Console.WriteLine("Comments on {0} : {1}",
                                           method.Name,
                                           authorAttributeAttr.Comments);
                 
                         Console.WriteLine(IsMemberTested(method) ? "Member {0} is tested!" : "Member {0} is NOT tested!",method.Name);
                     }

                 }
             }

             //Finding Field level (only public) custom Attributes
             foreach (FieldInfo field in type.GetFields())
             {
                 foreach (Attribute attr in field.GetCustomAttributes(true))
                 {
                     authorAttributeAttr = attr as AuthorAttribute;
                     if (null != authorAttributeAttr)
                     {
                         Console.WriteLine("Comments on {0} : {1}",
                                           field.Name, authorAttributeAttr.Comments);
                     }
                 }
             }
             Console.WriteLine("\n");
         }
    }
}

Output:


Tuesday, October 9, 2012

MSSQL SERVER 2008 – IntelliSense Does Not Work

Last few months ago I have upgraded Visual Studio 2010 ultimate with service pack 1. But unfortunately my SQL Server Management Studio(SSMS) 2008 intellisense not working. After searching I got that it is a common problem. Please have visit here.

To fix it just install SQL Server 2008 r2 SP1. You can download it from here.

If it is not working please check the following issues it may solve your problem.

  • Verify that the T-SQL Editor does not launch in SQLCMD mode Under Tools->Options->Query Execution->SQL Server->General, make sure “By default, open new queries in SQLCMD mode” is unchecked.
  • Go to Tools -> Options -> Text Editor -> Transact-SQL -> General -> IntelliSense
    Select Auto List Members and Check Parameter Information.
  • IntelliSense should be refreshed with the latest changes in database.
    1. Press CTRL+SHIFT+R
    2. Go to Edit -> IntelliSense -> Refresh Local Cache

Thursday, September 27, 2012

“The ‘VSTS for Database Professionals Sql Server Data-tier Application’ package did not load correctly”

After long time, I have got some relax from work pressures. I have got lots of mail about several issues. I had tried to give them hot fix with in a very short time. Sorry to everyone for my late response.

Today, when I am setting my new laptop I have faced a problem in VS 2010. Just run the VS2010 and got the error,
The ‘VSTS for Database Professionals Sql Server Data-tier Application’ package did not load correctly.
I don't understand why this is happening?

Potential cause:
This problem may occur due to install SQL Server Express 2008 with Visual Studio 2010 installation. When install SQL Server 2008 r2 on the same machine I had got an exception. So that I have uninstalled SQL Server Express 2008 from machine and then install SQL Server 2008 r2 but installation not completed successfully.

Solution 1:
I have got the solution from this link.
To fixed my problem I did the following tasks

Step-1: Run the Visual Studio 2010 Ultimate  disc
Step-2: Explore  \WCU\DAC folder from disc
Step-3: Now installed the three packages from the Visual Studio 2010 Ultimate disc and it fixed the problem right away for me.

Microsoft SQL Server 2008 R2 Data-Tier Application Framework with this command:
\WCU\DAC\DACFramework_enu.msi

Microsoft SQL Server 2008 R2 Data-Tier Application Project:
\WCU\DAC\DACProjectSystemSetup_enu.msi

Microsoft SQL Server 2008 R2 Transact-SQL Language Service:
\WCU\DAC\TSqlLanguageService_enu.msi

If required you can re-install the Visual Studio 2010 Service pack 1.

Solution 2:
You can also try with this solution though it is not tested
1. Open Visual studio 2010 command prompt
2. Right click on it to run as an Administrator
3. execute this command:  devenv.exe /resetskippkgs

FYI: For latest Microsoft SQL Server Data Tools visits here.

Thursday, August 16, 2012

KeyValue pair/Dictionary with duplicate keys

Very recently for my development purpose I need to use Dictionary. And it works very nicely. But problem occurred when requirement changes and face a scenario that duplicate key's are needed to handle in Dictionary which is not possible. So I had written a custom class to handle this problem,please suggests me if there is any better idea.

Examble:

public class KeyValuePair
{
public string Key { get; set; }
public int Value { get; set; }
public string HdValue { get; set; }

public KeyValuePair(string key, int value, string hdValue)
{
this.Key = key;
this.Value = value;
this.HdValue = hdValue;
}
}

Insert Data:
List<KeyValuePair> listKeyValuePair= new List<KeyValuePair>();
listKeyValuePair.Add(new KeyValuePair("TAX",2,"Income Tax"));
listKeyValuePair.Add(new KeyValuePair("TAX",4,"Vatlue added Tax"));
listKeyValuePair.Add(new KeyValuePair("PORT",9,"Vehicle Test"));


Sort Data:
List<KeyValuePair> listSorted = listKeyValuePair.OrderByDescending(x => x.key).ToList();


Filter Data:
var filteredData = listKeyValuePair.where(keyValue=> string.Compare(keyVaue.Key,"TAX")==0).ToList();
if(filteredData.Count > 0)
{
//Do something
}

Wednesday, August 15, 2012

Short circuit evaluations on && and || in JavaScript

Like many other languages Javascript’s && and || operators short-circuit evaluations,that is, for

&& if the first operand evaluates to false, the second operand is never evaluated because the result would always be false.
Similarly, for
|| if the result of the first operand is true, the second operand is never operated.

This means that in the following expression, x will never be compared to y.
true || x == y

This short-circuiting is great for performance, as it allows significant bits of calculations to be skipped. In addition to that, it lets you to write e.g. the following in one expression without getting an ‘object has no properties’ error:
oNode && oNode.firstChild

Be mindful though when using && with code that has side effects, e.g. say you have two objects with a hasError() method which return true or false depending on whether an error occurred and additionally output an error message:
x.hasError() && y.hasError()

Here, if x has an error, y will never be evaluated and thus the error message will never be shown.

For more details pls visits this and that.

Monday, July 2, 2012

Login failed for user 'NT AUTHORITY\NETWORK SERVICE'

Very recently I got a mail from a junior guy he faced a problem every time when he installed the SQL server database on his workstation. But he failed to understand what is the main reason behind this. The problem was that after installing SQL server database his working web sites were throws exception like this...

System.Data.SqlClient.SqlException: Login failed for user 'NT AUTHORITY\NETWORK SERVICE'

Reason
The main reason behind this error occurs when you configured your web site with IIS. When any one tries to browse the site, IIS send the request to the SQL server with credentials. But unfortunately the credential do not have proper permission. So that it throws exception.

Solution
We can solve this problem in several ways....
First solution that resolved my problem was:

  1. Login to SQL server database via SQL Server Management Studio
  2. Go to the "Security" directory of desired database
  3. Right-click the Users directory
  4. Select "New User..."
  5. Add 'NT AUTHORITY\NETWORK SERVICE' as a new user
  6. In the Data Role Membership area, select db_owner
  7. Click OK




Second solution
If 'NT AUTHORITY\NETWORK SERVICE' user is already added on Users lists then we can move with this second workaround.

  1. Login to SQL server database via SQL Server Management Studio
  2. Go to "Security" directory 
  3. Select "Logins" directory under "Security" directory 
  4. Right click on NT AUTHORITY\NETWORK SERVICE and select Properties
  5. New popup window appear, select "User Mapping" tab
  6. Under  "User Mapping" tab select the desired database
  7. In the Database Role Membership for area, select db_owner role
  8. Click OK









For more information about sql server 2008 installation  please visits.

Monday, May 28, 2012

Custom paging,sorting and filtering data with Dynamic query

Sometime it becomes very essential for us to write dynamic query for custom paging,sorting and filtering data. Today I want to share simple one which may help others to fulfill their requirements.


Sample stored procedure:


CREATE PROCEDURE [dbo].[spGetAllTag]
@SearchText varchar(50),
@PageIndex INT = 1,//page number like 1,2,3
@PageSize INT =10,
@SortCol varchar(100),
@TotalCount int output
As
Begin

;WITH PagingCTE (Row_ID,ID,Tags,Weight,CreatedBy)
     AS
      (
      SELECT
            ROW_NUMBER()
                  OVER(ORDER BY
                         CASE WHEN @SortCol='Name DESC' THEN [NAME] END DESC,
                         CASE WHEN @SortCol='Name ASC'  THEN [NAME] END ASC,
                         CASE WHEN @SortCol='CreatedBy DESC' THEN CreatedBy END DESC,
                         CASE WHEN @SortCol='CreatedBy ASC'  THEN CreatedBy END ASC,
                         CASE WHEN @SortCol='Weight ASC'   THEN Weight  END ASC,
                         CASE WHEN @SortCol='Weight DESC'  THEN Weight  END DESC

                        ) AS [Row_ID],
ID,
[NAME],
Weight,
CreatedBy

FROM TabularWeight
WHERE [Name] LIKE @SearchText + '%'
         )

       SELECT
            Row_ID,
            ID,
            [NAME],
            Weight,
            CreatedBy
         
      FROM PagingCTE
      WHERE Row_ID >= (@PageSize * @PageIndex) - (@PageSize -1) AND
            Row_ID <= @PageSize * @PageIndex

select @TotalCount = count(1) from dbo.TabularWeight where [Name] LIKE @SearchText + '%'  
   
End
GO