Sunday 23 October 2011

Factory Design Pattern C# Code example




Introduction:

It separates the object creational logic and reduces coupling between classes. Usually, when there are multiple classes inheriting from same base class, it is recommended to use a factory design pattern.

Noob implementation:


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Factory
{
    public abstract class DbServer
    {
        //method need to be implemented by inherited classes
        public abstract string GetDbServerName();
    }
    public class MsSqlServerDb : DbServer
    {
        //overridden method
        public override string GetDbServerName()
        {
            return "MS Sql Server";
        }
    }
    public class OracleDb : DbServer
    {
        //overridden method
        public override string GetDbServerName()
        {
            return "Oracle Database Server";
        }
    }
    //factory class that will be used to create objects
    public static class DatabaseFactory
    {
        //return the required object
        public static DbServer GetDb(string DbName)
        {
            if (DbName == "Ms Sql Server")
            {
                return new MsSqlServerDb();
            }
            if (DbName == "Oracle Database Server")
            {
                return new OracleDb();
            }
            return new MsSqlServerDb();

        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            //get the ms sql server object
            DbServer dbServer = DatabaseFactory.GetDb("Ms Sql Server");
            //return ms sql server
            string dbName = dbServer.GetDbServerName();
            //print the name on output window
            Console.WriteLine("Server Name : " + dbName);
            //get the oracle database server object
            dbServer = DatabaseFactory.GetDb("Oracle Database Server");
            //return oracle server name
            dbName = dbServer.GetDbServerName();
            //print the name to output window
            Console.WriteLine("Server Name : " + dbName);
            Console.Read();
        }
    }
}




Noob implementation does not adhere to OPEN/CLOSE PRINCIPLE, which states that classes should be open for extension but modification, should not be allowed.

To overcome this issue, we can use “class registration approach," implementation as below.


Class Registration:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Factory
{
    public abstract class DbServer
    {
        //method need to be implemented by inherited classes
        public abstract string GetDbServerName();
        public abstract DbServer CreateDbServer();
    }
    public class MsSqlServerDb : DbServer
    {
        //overridden method
        public override string GetDbServerName()
        {
            return "MS Sql Server";
        }

        public override DbServer CreateDbServer()
        {
            return new MsSqlServerDb();
        }
        public static void RegisterDbServer(string dbName)
        {
            DatabaseFactory.RegisterDatabaseServer(dbName, new MsSqlServerDb());
        }
    }
    public class OracleDb : DbServer
    {
        //overridden method
        public override string GetDbServerName()
        {
            return "Oracle Database Server";
        }

        public override DbServer CreateDbServer()
        {
            return new OracleDb();
        }
        public static void RegisterDbServer(string dbName)
        {
            DatabaseFactory.RegisterDatabaseServer(dbName, new OracleDb());
        }
    }
    //factory class that will be used to create objects
    public static class DatabaseFactory
    {
        public static Dictionary<string, DbServer> dbDictionary = new Dictionary<string, DbServer>();
      
        public static void RegisterDatabaseServer(string dbName, DbServer dbServer)
        {
            dbDictionary.Add(dbName, dbServer);
        }

        public static DbServer GetDb(string DbName)
        {
            DbServer dbServer = new MsSqlServerDb();
            if (dbDictionary.ContainsKey(DbName))
            {
                dbServer = dbDictionary[DbName];
                return dbServer.CreateDbServer();
            }
            return dbServer.CreateDbServer();
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            //registeration
            MsSqlServerDb.RegisterDbServer("Ms Sql Server");
            OracleDb.RegisterDbServer("Oracle Database Server");

            //get the ms sql server object
            DbServer dbServer = DatabaseFactory.GetDb("Ms Sql Server");
            //return ms sql server
            string dbName = dbServer.GetDbServerName();
            //print the name on output window
            Console.WriteLine("Server Name : " + dbName);
            //get the oracle database server object
            dbServer = DatabaseFactory.GetDb("Oracle Database Server");
            //return oracle server name
            dbName = dbServer.GetDbServerName();
            //print the name to output window
            Console.WriteLine("Server Name : " + dbName);
            Console.Read();
        }
    }
}




Friday 21 October 2011

Deploying ASP.NET MVC 2.0 web application on IIS 7.0 in Production Environment



In this article, I am going to explain how we can deploy asp.net mvc 2.0 application on IIS 7.0 in a production environment. Furthermore, I will highlight some configuration which we normally ignore, but they can greatly improve website performance and help us for smooth deployment.

·         System.Web.Mvc
·         System.Web.Routing
·         System.Web.Abstractions
One possible problem could arise if hosting server have both asp.net mvc 2.0 and asp.net mvc 3.0 installed, and you tried to access asp.net mvc 2.0 website. Error details are as below:

Parser Error Message: The type 'System.Web.Mvc.ViewMasterPage' is ambiguous: it could come from assembly 'C:\Windows\assembly\GAC_MSIL\System.Web.Mvc\2.0.0.0__31bf3856ad364e35\System.Web.Mvc.dll' or from assembly 'C:\Windows\Microsoft.Net\assembly\GAC_MSIL\System.Web.Mvc\v4.0_3.0.0.0__31bf3856ad364e35\System.Web.Mvc.dll'. Please specify the assembly explicitly in the type name.

<runtime>
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
      <dependentAssembly>
        <assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35" />

        <bindingRedirect oldVersion="1.0.0.0-3.0.0.0" newVersion="2.0.0.0" />
   
  </dependentAssembly>
    </assemblyBinding>
  </runtime>

The first step in a deployment process is to publish the website on a local drive. Right click on the website in a visual studio solution pane and select publish, then in publish dialog select publish method as File System and target location to any local drive location.








While publishing website don’t leave <compilation debug=”true”/>. The biggest disadvantage of it is that scripts and images downloaded from webresource.axd handler are not cached.
As a result, it will slow the down the web page loading, because with every request from browser, fresh copy of JavaScript files and static resources need to fetch from a server. For more details visit this link (http://weblogs.asp.net/scottgu/archive/2006/04/11/442448.aspx)
Next step is to Copy and move published folder to hosting server. Click on start menu type ‘inetmgr’ in run command and press enter it will open up IIS interface.

Add Application Pool in IIS 7.0

Create the application pool for your application by right clicking in application pool and click on add application pool from context menu



In add application pool dialog select framework version .NET 4.0 name it such as ‘newApplicationPool’









You can change the identity property to either built in account or a custom account according to your requirement.


By default one application pool has one worker process within which asp.net application runs, it is recommended to create a separate application pool for each web application, which has many advantages, for example.

1)      App pool can run with different identities so you can apply restriction this way
2)      You can restart/recycle an app pool without affecting other applications
3)      If one app pool crashes it does not affect other applications
4)      Each app pool has its own address space in memory
On other hands, one application pool can have many applications with similar configuration. In this case, each web application has its own appDomain under which application runs. So if one of the applications, sharing application pool, fails it does not impact the other application sharing this application pool because of appDomain. However, if a worker process crashed, then it will affect all the applications sharing the application pool as stated earlier.


Usually, one application pool has one worker process. Nevertheless, you can create multiple worker process for single application pool, which called a web garden. However, this configuration has its own requirement like you cannot use session state ‘In Proc’ as it going to be shared by processes. You have to change mode to ‘Out proc’ such as state server or ms sql server.

How To create a web garden in IIS 7.0

Select the application pool for which you want to have multiple worker process select the advance settings and enter the ‘maximum number of worker processes’

 

Add New Web Site in IIS 7.0

Now right click on sites folder and select add web site

Next, in add web site dialog enter site name like ‘NewWebSite’ and select the application pool we have created earlier for website, which is ‘NewApplicationPool’. Next enter the physical path of published code in hosting server. Now in binding section, make following entries. Select http for type, left IP address and port fields as default and in a host name, field enters a web site url like ‘www.NewWebApplication.com’


References: