Wednesday, April 23, 2014

String value for Enum type

 
As you all know, we have lots of controlled string values in the system. We wish we could define them in the same way we defined  controlled numeric values, Enum.
 
Since it is not possible as Enum type cannot Inherit from string type.  We settle with something not ideal.
 
If we really want to make it a controlled list, we make a class full of  constaint values. An example will be  DataEntities.Common.VehicleBodyStyle.
 
If we take a easy way out, we sacrifice the controllibliblty and define a list of constants in DataEntities.Common namespace and use some kind of prefix for the name of constants. A good example will be IRP Web Service Constants.     
 
Public Const IRP_MODEL_TYPE_ROAD_TRACTOR As String = "RT"
Public Const IRP_MODEL_TYPE_TRUCK As String = "TK"
Public Const IRP_MODEL_TYPE_TRACTOR As String = "TR"
Public Const IRP_MODEL_TYPE_TRUCK_TRACTOR As String = "TT"
Public Const IRP_MODEL_TYPE_WRECKER As String = "WR"
Public Const IRP_MODEL_TYPE_WRECKER_PLUS As String = "WK"
Public Const IRP_MODEL_TYPE_BUS As String = "BU"
Public Const IRP_MODEL_TYPE_MOBILE_HOME_TOTER As String = "MT"
 
If we take a closer look at Enum type. Each enum value has a name in string, and a value in numeric ( int16, Int32, or Int64). Some time, if we do not care about the numeric value of the enum value, we just let the compiler take care of it… if we want it to have some string value, we could name the Enum after the string Values we want it to be. However, there are 2 problems with this approach 1) by doing so, we may have to sacrifice some readiblity, 2) what if there are some spaces in the string value we want to us.
 
Well, I did some research on it and I figured a way to assign a string value to each enum type value in addition of it numical value and the name.
 
 The solution consits one small class and 2 extended methods.
 
StringValueAttribute class made it possible to provide a string value for each enum value.
 
 
GetEnumValue (of T) method convert a string value to a enum value based on the string value set in its enum definition.
 
GetStringValue method retrieve the string value from a enum value…
 
Enough talking, let’s take a look at some code.
 
This is how we define enum type with String Value:
 
 
Public Enum VehicleBodyStyles
        <StringValue("PU")> PickUp
        <StringValue("VA")> Van
        <StringValue("2D")> TwoDoor
        <StringValue("4D")> FourDoor
        <StringValue("AM")> Ambulance
        <StringValue("BU")> Bus
        <StringValue("CN")> Cnvertbl
        <StringValue("DM")> Dump
        <StringValue("HR")> Hearse
        <StringValue("IN")> Incmplt
        <StringValue("LS")> LowSpeed
        <StringValue("MC")> Mtrcycle
        <StringValue("ME")> MotorizedHome
        <StringValue("MX")> Mixer
        <StringValue("PC")> ParkCamper
        <StringValue("PN")> Panel
        <StringValue("RD")> RoadSter
        <StringValue("SW")> StakeOrRack
        <StringValue("BU")> StationWagon
        <StringValue("TC")> TrialerCoach
        <StringValue("TK")> Tank
        <StringValue("TR")> Trailer
        <StringValue("TT")> Tractor
        <StringValue("UT")> Utility
        <StringValue("2W")> TwoWheel
        <StringValue("3W")> ThreeWheel
        <StringValue("MW")> MultipleWheel
        <StringValue("AI")> Air
        <StringValue("TV")> TrackVehicle
        <StringValue("MH")> MobileHome
        <StringValue("PM")> ParkModel
        <StringValue("WR")> TowTruckOrWrecker
        <StringValue("24")> Camper
        <StringValue("MP")> Moped
        <StringValue("SM")> SnowMobile
        <StringValue("RT")> RoadTractor
        <StringValue("WR")> Wrecker
        <StringValue("WK")> WreckerPlus
        <StringValue("MT")> MobileHomeToter
    End Enum
 
 
This unit test shows you how to convert string value to enum value and how to retreive string value from a enum value:
 
<TestMethod()> Public Sub StringValueTest()
   Dim vehicleBodyStyle As VehicleBodyStyles
   Dim myStringValue = "BU"
   Assert.IsTrue(myStringValue.IsMember(Of VehicleBodyStyles)())   vehicleBodyStyle = myStringValue.GetEnumValue(Of VehicleBodyStyles)()
   Assert.AreEqual(VehicleBodyStyles.Bus, vehicleBodyStyle)
   Assert.AreEqual(myStringValue, vehicleBodyStyle.GetStringValue())
   Assert.AreEqual(5, DirectCast(vehicleBodyStyle, Int32))
   Assert.AreEqual("Bus", vehicleBodyStyle.ToString())   myStringValue = "Van"
  
Assert.IsTrue(myStringValue.IsMember(Of VehicleBodyStyles)())   myStringValue = "Something"
   
Assert.IsFalse(myStringValue.IsMemberOf(Of VehicleBodyStyles)())
End Sub
 
 
<TestMethod()> Public Sub FlashTypeTest()
   
Dim flashTypeIntegerValue As Int32 = 5
   
Dim flashTypeEnumValue As FlashType
    flashTypeEnumValue =
DirectCast(flashTypeIntegerValue, FlashType)
    Assert.AreEqual(FlashType.Type5, flashTypeEnumValue)
    Assert.AreEqual(
"05", flashTypeEnumValue.GetStringValue())
    Assert.AreEqual(
"05", DirectCast(flashTypeIntegerValue, FlashType).GetStringValue())    
    flashTypeIntegerValue = 12
    flashTypeEnumValue =
DirectCast(flashTypeIntegerValue, FlashType)
    Assert.AreEqual(FlashType.Type13, flashTypeEnumValue)
    Assert.AreEqual(
"13", flashTypeEnumValue.GetStringValue())
End Sub

Hybrid in Methodology - Recipe for failure

Many government  IT projects, by regulation, are made as fix bid projects. On the other hands, the government agencies do not feel comfortable to see the IT venders spend more than a half of project budget producing all kind of requirement documents, design documents, architecture documents without producing one line of production code. With that consideration, they start to demand the IT venders to produce workable solution in phases or iterations,  most likely the use cases are grouped into iterations. The same trend also extended to private sections as agile methodology become more and more accepted by the industry. 

This presents a great challenge for many IT venders. From contract point of view, we are doing some kind of fix scope, fix budget, fix duration project. From delivery point of view, we are required to provide interim feature releases. We, IT vender, need to stand up to this challenge to delivery high quality IT solution for our clients.

This is what happens In a typical RUP project:

We get all  use cases documented and bring them to design phase. In design phase, we take in all use cases as input together with all non-functional requirements and produce a holistic design for the system. The output of the design phase includes package diagrams,  component diagrams, class diagrams sequence diagrams  and wireframes in conjunction with supplementary design documents in various levels. Then we bring all these design artifacts into construction phase. In construction phase, we assign WBS (Work Breakdown Structure) to each development team member, then track them in MS Project or in a Excel file. More than often, these are in the detail level of “develop a method in a specific class”. When all WBS are completed,  the team start to do Integration Test and resolve all identified defects in stabilization phase.  After that,  the system goes to production and Production Support phase gets started. Some time, a new project aim further enhance the product gets kicked out when current version of the system is in product support phase.

In this process, there are a few important characteristics. First of all, there are exit criteria defined  for each phase, at end of each phase, some kind of sign off need to happen. Once a specific artifact is signed off, any further change will go through change control process. Secondly, the transformation from use case to component design is done in the design phase. When the programmers are given a WBS to work on, that is not directly related to one specific use case, instead it is directly related to a specific part of a component.

It is imperative that the team executes each phase in accordance to the exit criteria defined. Requirement review, design review and code review need to be conducted to ensure there is nothing missed before moving on to the next phase.

However, I have seen many failed project making the following common mistakes:

1.       Due to lack of visibility, most of ( if not all) parties have difficult in visualize the envisioned solution. Hence the reviews of these produced artifacts become less meaningful.

2.       In order to secure client sign off on these artifacts, the team spent too much time on documentation, the visual format of these artifacts. So much so that, they eats in the time and budgets allocated to construction phase and stabilization phase.  Which in turn directly result in poor quality of the final product.

3.       Due to the rigid change process, even the team produced documented system, it is less useful to the business due to mistakes made in  these signed off artifacts and the change in business operation. 

This is what happens In a typical Agile project:

The contract is usually signed as “Time and Material “ based.  In each iteration, user oriented features are put in development. A project architect works with the development team providing architecture guidelines, principles, sometime even get involved in detail design of the user oriented feature.

One of most important characteristics is that when the team is working on a feature in current iteration,  it is very well possible that the user community is still working on the business requirement of another feature.  But the development team does not have visibility to what are in the pipeline. As the result of it, the team could not come out with a holistic design before the first line of the code is written. More than often, in order to have seamless design for both features, change in the formal design is needed. It is not correct to say “ in agile, they do not do design, or design is not needed”.  In the reality in a success Agile project, the team are doing design all the time and change the design all the time.

Due to the limited visibility in requirement, It is imperative that the all team members are encourage to do refactoring throughout the project duration from first iteration to the last when they are given a new feature to development.

In this ever changing code base, it is imperative to implement automat unit test and continuous integration build process to safeguard the produced features when the new features are been developed.

However, I have seen some failed projects making some kind of common mistakes which contributed to the failure of the project:

1.       They totally eliminated design element from the project, the codebase become disorganized collection of code blocks. So much so that the team has to start over again.

2.       They do not dare to do refactoring existing code as new features are put in development. Which result in repetition, confuted, un-maintainable code base     

3.       To “save” time, the team decide not to engage in automated unit test authoring.  As the team doing refactoring, the stability of the codebase are greatly comprised. 

The other common mistakes I have seen in projects using the disconnect between the development community and the rest of the project team and individuals are given the task to do what they are not equipped to do.

The disconnection is reflected in following symptoms:

1.       The user / business analysis  do not read the design document

2.       architect / designer do not read the requirement document

3.       architect / designer do not read the code

4.       developers/ programmers do not read the design document


The justifications cited are often “ there are too much documentation, I simply do not have time to read them. If I read them all, I would not have time to do my work.”     The result of this symptoms is that there are contradicting among these artifacts, more than often  the discrepancy between the requirement and the code written is largest among all.    
 
Skill and task mismatch is reflected in following symptoms

1.       involving user and business analysis in design activities under the name of JDS ( Join Design Session) . In these  produced  High Level Design Document (HLD), the design decisions  made by non-professional designer  are documented as requirements. On the other hand,  because it is “high level” by definition, it lack of business requirement details.

2.       The team is constantly under pressure to meet delivery timelines. To meet the changeling timelines, the team is forced or choose to cut Connors and take up technology debts. These Connors cutting and technology debts taking produce long lasting impact in overall project health, which costs much more to recover from at the later time of the project. I have seen many projects failed because of just that. 

Okay,  if you are still reading, you must eager to know what is my solution for all these. May be you have seen some project failures like I have. Let me get to that.
 

1.       Regardless how the project is structured in the contractual expect, if you go with RUP process, execute it as it should be done, if you go with Agile process, execute it as it should be done. The worse case is that you give up the principles of RUP process with the reason that client wants to have interim delivery, and you give up the principles of Agile process because the client wants to have a fix bid project.  That is the best recipe for failure. If you call it hybrid, that is not the hybrid you want to have in your project.

2.       If you want to directly put use case / requirement into development process, you are doing agile. So refractory, unit tests, continuous build are your best friend.

3.       If you want to have holistic design in place before the development effort is started, you are doing URP.  So exit criteria, review process need to be formalized. Change control needs to be both formalized and flexible enough.

4.       In any case, let SMEs provide the requirement, let the professional designer / architects do the design and let the developers do the development. In another word “let the people do what they do the best”.  In agile process, all development team members are both designers and developers, they need to be equipped with the skill to do the job. To address that, pair programming would be a great help as a form of OJT (On Job Training), The overall cost of pair programming is much smaller than most people thought to be.

5.       In any case, if your team have some talking heads, remove them from the project. They are over-head cost to the project without adding value. When I said “talking head”, I refer to these who are involved everywhere but are not good anywhere.  Specifically, they talk a lot project management terms but does not carry PM responsibility; they  talk a lot business terminologies but do not carry BA responsibility; they talk a lot technology terms but not equipped with the technical skills in the specific platform the envisioned system is to be built on to be effective either as architect or  developer.

6.       In any cases, integrated ALM implementation with IDE will greatly improve your chance of success. 
 
7.    In any case, an individual is capable or not to take up a specific task is not based on who he or she is rather than based on what skills he or she possesses. give them the task they can perform is better than give them the task they are suppose to perform based on their title or role in the project.   

Friday, April 18, 2014

Anti-pattern for April , Golden Hammer


The anti-pattern for April Golden Hammer:  http://deviq.com/golden-hammer

 
The elaboration for the anti-pattern is: Stand back! I have just the tool to solve this.

The description for the anti-pattern is: A language, tool or platform with which the developer is comfortable and productive, so they are tempted to use it for any problem that presents itself.


The further elaboration from the web site is read as the following:
 

The Golden Hammer refers to a language, tool, or platform with which the developer is comfortable and productive, so they are tempted to use it for any problem that presents itself.  As the saying goes, "If all you have is a hammer, everything looks like a nail." (Maslow's Instrument)  Sometimes the Golden Hammer is the database, and logic that would be better of in the application ends up in the database because someone is more comfortable with SQL than with the application language.  Sometimes the reverse is true, and database-centric logic ends up in the application.  Other times, the tool in question can be the choice of application platform, with an application being built as a web or desktop application because that's where the developer feel comfortable, rather than because it's the best solution to the needs of the client.  Many developers love new things, so sometimes they fall victim to the Shiny Toy antipattern, and in such cases it's not uncommon for them to treat their new Shiny Toy like a Golden Hammer, too. For example, when XML first became popular, developers tried to use it for everything, even many things for which it wasn't necessarily well-suited

 

The quote on the calendar is:

 

I suppose it is tempting, if the only tool you have is a hammer, to treat everything as if it is a nail.

 --Abraham Maslow

 In about 2 years ago, I wrote a blog page in my blog titled “when you have a hammer in your hand, everything looks like nail to you”

 

http://peterluzc.blogspot.com/2012/07/when-you-have-hummer-in-your-hand.html for these did not get a chance to read it and have some interest in reading it, I put the link here.

 
The solution for this anti-pattern is enriching your tool box, enhancing your skillset. Use the right tool for the task, and use the tools in the way it is designed to use.
 

To do that, it requires lots of learning and practicing… if you are as passionately as I am or even more, you will find learning is fun and rewarding

As some of you know, I recently picked up iOS app development. I spent many late nights and weekends on X Code and Objective C, I find lots of fun in doing so. ..  if I would insist to write iOS, objective C program in the way I write C# code, I am sure  I were be heading to no way….

 Hopefully, I will be able to publish an app in iOS in the near future…

Monday, April 14, 2014

ASP.Net Session State

If you do a search on the web for "ASP.NET Session State", you would probably get those  links from MSDN

http://msdn.microsoft.com/en-us/library/ms178581.aspx and
http://msdn.microsoft.com/en-us/library/ms178586(v=vs.100).aspx

Basically you are offered with 3 options:

1.      In Process
2.      State Server
3.      SQL/Server

Beyond that, you are on your own.

Well, In a typical enterprise system, server farm or some kind of load balancing are considered as typical configuration in most of the deployment environment. Let's look at each of these options in the context of service farm.

1)      In Process: yes, it is fast, but the session does not go beyond its own server, when a server is down (scheduled or unscheduled), so are these sessions with it. Yes, Sticky IP load balancer can reduce the negative impact of it, but when a server is down, these sessions with that server are also gone. Which may comprise the user experience for those with active sessions with the system. Secondly, "stickiness" offered by the load balancer could generate some kind uneven load among server behind the load balancer.  It is clearly not a preferred choice for enterprise web application.
2)      State Server:  the difference between state server and in process option is that in state server case, the state server is running its own process. We could configure your ASP.NET app in each server to use the state server in their respective servers, you could also configure them to use a shared state server instance. In the first configuration, it is the same as in process, when a server is down, all the active sessions are gone with it. In the second configuration, we achieved mobility of the session among member servers. So that we do not require the load balancer to provide "Sticky IP" balancing, but it offers a bigger problem, "Single Point of Failure" .Because in this configuration, when the computer host the State Server is down or the State Service on the computer is down, the entire site is down, regardless how many computers are behind the load balancer. It is also not a preferred choice for enterprise web application.
3)      SQL/Server: it addressed the SPoF issue posed by state server solution, but there are 3 issues with its solution: 1)  if the SQL/Server is down, so is the entire system. 2) To address that issue, you would have to configure a cluster SQL Server, but it is much expensive than any other solution. 3) Most of public facing web sites are hosted in DMZ zone. And you seldom see infrastructure architects allow a SQL/Server (let alone cluster SQL/Server ) to be installed in DMZ zone. So even though it is a possible solution, but in most of cases it not feasible.


 So the industry is looking for some kind of state management solution with following characteristics:

1)      fault tolerance
2)      session mobility
3)      high performance
4)      low cost


Well, there are many solutions on the market as of today, some are cloud implementation, and some are for in-promise implementation. In this article, I will pick one in each category as a form of introduction


1.      N-cache, In-Memory Distributed Cache for .NET

The following link offers the product overview on NCache, http://www.alachisoft.com/ncache/,  as indicated in the title, it is In-Memory Distributed Cache for .NET. it is running in the memory of each member servers, so it is as fast as state server. It is distributed, the sessions created in one member server get replicated to other member servers, so it achieved session mobility. As it is kind of plug and play, no code changes is involved, all we need are 1) install the product 2) change the web.config file to use the service.  In term of cost, it is a product offered by Alachisoft, you can download the product from its site and give it a try. I could not image it is more expensive than the cost of a cluster SQL/Server Box, not even a faction of it.


2.      Microsoft Azure Cache Cloud implementation

Not too long ago, Microsoft Azure launched a Cache service in data service category. The following link provided step by step instruction on how to implement Session state using Azure cache. http://azure.microsoft.com/en-us/documentation/articles/web-sites-dotnet-session-state-caching/ , I personally created a cache in my Azure and use it in my web site hosted in Azure, it works well for me... however, as my site is "Shared" site, not even single server side, so I could not verify the effect when the site is running behind the load balancer. But form programming point of view, it is very simple. You will get it done within an hour.

From cost point of view, for a cache with capacity up to 128M and scale to up to 8 units, it is about $12.5 a month. At the high end, you can get 10 caches with the capacity up to 5G and scale to up to 30 units with high availability and notification feature at $200 a month.


In conclusion, both solution eliminated "single Point of Failure" in Session State management, offered session mobility , high performance and low cost.

Monday, March 31, 2014

Anit-pattern of March-- Found on Internet - The Internet can cure all of your problems

 
 
The elaboration says:
 
The practice of using code and techniques found on the internet without taking time to validate the source and ensure it is credible.
 

 This link provide some further reading on the anti-pattern ( including an interesting photo). for your convenience, I copied some here:
 
This anti-pattern refers to the practice of taking advice or code samples found on the Internet and immediately applying them to production code without taking the time to consider their effects. It's true the Internet is a huge source of knowledge, but it's also true that getting published on the Internet is not a particularly difficult task, and the peer review process is usually non-existent. Before trusting that a technique or code snippet found somewhere on the Internet, consider its source, and ideally try and apply it in a non-production environment first to ensure it does what you expect.
 
In my past 10 years working experience in software development business, I could say that I could not live without Internet, more specifically, I could not live without Internet search! Google created a new Internet time after World Wide Web became part of our life starting the second half of 90s. However, there is so much information on the internet, so much resource on the internet.  For the same topic you can find articles with total opposite opinions. logically, at least one of them is wrong.
 
One would asked “are we going to stop searching on internet?”  absolutely NOT. The key point here is “validation”. First of all, you want to ensure it is from reputable source or it is endorsed by reputable party. If it is from a personal blog, you want to take extra  effort to verify it. For “open source” solution, you want to get the source code, and verify the source code before putting it in production system. Accurate test, security test, reliability test need to be conducted on these “open” products before use them in commercial software development.
 
When you are very excited about something you found on internet, that is the time you need to sit back and do some homework before jump on your feet.

using HTTP Client to interact with Restful service created with ASP.Net WebAPI

Refer back to the article on how to implement CRUD operation using WebAPI. Today I am going to show you the other side of the story.
 
The code is surprisingly simple, let me show you one by one:
 
  1. Create
 
public async Task<bool>CreateAsync(Person person)
        {
            HttpResponseMessage response = await PostAsJsonAsync<Person>(ServiceUris.ControllerBaseAddress, person);
            return response.IsSuccessStatusCode;
        }
 
  1. Read all
 
        public async Task<IEnumerable<Person>> GetAsync()
        {
            var response = Get(ServiceUris.ControllerBaseAddress);
            if (response.IsSuccessStatusCode)
            {
                return await response.Content.ReadAsAsync<List<Person>>();
            }
            else
            {
                return null;
            }
        }
 
  1. Read one
 
         public async Task<Person> GetAsync(int id)
        {
            var response = Get(UriAddress(id));
            if (response.IsSuccessStatusCode)
            {
               return await response.Content.ReadAsAsync<Person>();            
            }
            else
            {
                throw new HttpClientException(response);
            }
        }
 
  1. Update
 
        public async Task<bool> UpdateAsync(Person person)
        {
            var putUri = UriAddress(person.Id);        
            Debug.WriteLine(putUri);
            HttpResponseMessage response = await PutAsJsonAsync<Person>(putUri, person);
            return response.IsSuccessStatusCode;
        }
 
  1. Delete
 
public async Task DeleteAsync(int id)
        {
            await base.DeleteAsync(UriAddress(id));
        }
 
 
The constructor of the class is looks like the following:
 
 
public PersonManager(string baseAddress)
            : base(baseAddress)
        {
        }
 
I have a few unit test cases for it, let me show you some:     
 
 
 
        [TestMethod]
        public void PersonManagerGetAsyncTest()
        {
            var target = new PersonManager(TestSettingsLocal.ServiceBaseAddress);
 
            var result = target.GetAsync().Result;
 
            Assert.IsNotNull(result);
 
            foreach (var p in result)
            {
                Debug.WriteLine(p.ToString());
            }
        }
 
        public void PersonManagerGetAsyncByIdTest()
        {
            var target = new PersonManager(TestSettingsLocal.ServiceBaseAddress);
 
            var result = target.GetAsync(1).Result;
 
            Assert.AreEqual("Peter", result.FirstName);
            Assert.AreEqual("Lu", result.LastName);
 
        }
 
You might notice that the code here is very simple, it does not even have HTTP related code. Well the code here is simple is because there is a base class does all the heavy lifting behind the scene. This is how the class is defined.
 
 public class MyServiceProxy : ProxyBase
{
}
 
 
For these who are interested to see how ProxyBase is written, please drop me an email, I will send you the source code for the base class.
 
 
 

Thursday, March 6, 2014

Web Configuration Transformation and Web Project Deployment

I thought to share something I first learned back in 2011 when I prepared for Microsoft certification examination for ASP.Net 4.0.  latterly I put it in use in my project. Since I put it in use, I start to appreciate it more. I could not think otherwise how could I do it without significant development effort. (of course, nobody wants to write code if we do not have to!). It has some relevancy to what we do in our project and if you are using VS2010 or above or thinking of using VS2010 or above for your Web app, whether it is classical ASP.Net form or MVC, you will find it interesting. Especially those who are involved in build/ deployment or tokenization process might find it useful or at least you will have an alternative to what you are using now in designing deployment strategy Visual Studio 2010.



ok, let me get it started…



Before Visual Studio 2010, ( like Visual Studio 2008 we are using), when you create an ASP.Net Web Project, IDE will add a Web.Config file to your project. if you want to have different setting in different regions ( Test, Staging or Production), you need to replace the region specific setting in the web.config file yourself. Some do it manually, some create some kind tokenization process to handle it. In order to deploy the project to a server you need to add a Web setup project in your solution and configure it to make a MSI file then copy the MSI file to the server you want to install and install the MSI package there.



This scenario is not ideal by all measures. If you are doing it manually, you tend to make mistakes as humans always do, if you are doing it using a tokenization tool, you will have one more step to worry about… as for MSI file installation, there are many shortcoming associate with it  If you want to use the built-in publishing process, you will find difficult to do the tokenization process.



well, starting with Visual Studio 2010, Microsoft introduced a process call “Configuration Transformation”.



After a Web project is created, you will see not only Web.config file, but also 2 files under it. please refer to the screen shot below:


 The 2 new files you did not see in Visual Studio 2008 are Web.Debug.config and Web.Release.config file.  “Debug” and “Release” is directly link to the default “Build Configurations” IDE created for you, Debug mode and Release mode. If you want to created more Build configuration using “Configuration Manager”, you will be able to add new “Config Transformation” for the new build configuration you created.  As you can see in the following screen shot, after I created a new Build Configuration, “Staging” I can add Config Transformations, and after I do  that I got one more file created



Let’s say in your project you have a DB connection and a setting, which will be different in different region.. you will most likely have your web.config file like the following:

<connectionStrings>

    <add name="ApplicationServices"

         connectionString="data source=.\SQLEXPRESS;Integrated Security=SSPI;AttachDBFilename=|DataDirectory|\aspnetdb.mdf;User Instance=true"

         providerName="System.Data.SqlClient" />

  </connectionStrings>

  <appSettings>

    <add key="BaseAddress" value="http://localhost:3593/"/>

  </appSettings>



then you will have the same setting but different values in these Config Transformations.



Release:

<connectionStrings>
    <add name="ApplicationServices"
         connectionString="Data Source=ProdServer;Initial Catalog=ProdDB ;Integrated Security=SSPI;"
         providerName="System.Data.SqlClient" />
  </connectionStrings>
  <appSettings>
    <add key="BaseAddress" value="http://ProdServerAddress/"/>
  </appSettings>


Debug:

<connectionStrings>
    <add name="ApplicationServices"
         connectionString="TestServer;Initial Catalog=TestDB ;Integrated Security=SSPI;"
         providerName="System.Data.SqlClient" />
  </connectionStrings>
  <appSettings>
    <add key="BaseAddress" value="http://TestServerAddress/"/>
  </appSettings>


Staging:

<connectionStrings>
    <add name="ApplicationServices"
         connectionString="StagingServer;Initial Catalog=StagingDB ;Integrated Security=SSPI;"
         providerName="System.Data.SqlClient" />
  </connectionStrings>
  <appSettings>
    <add key="BaseAddress" value="http://StagingServerAddress/"/>
  </appSettings>


But if we stop like that it won’t work. This is the time to introduce transformation process.  just pick up any of these transformations as an example: ( let’s say I pick Release), I need to add some transformation code in the transformation file:


Release:

  <connectionStrings>
    <add name="ApplicationServices"
         connectionString="Data Source=ProdServer;Initial Catalog=ProdDB ;Integrated Security=SSPI;"
         providerName="System.Data.SqlClient"  xdt:Transform="SetAttributes" xdt:Locator="Match(name)/>
  </connectionStrings>
  <appSettings>
    <add key="BaseAddress" value="http://ProdServerAddress/" xdt:Transform="SetAttributes" xdt:Locator="Match(key)"/>
  </appSettings>


What does it mean here? for the first one, it means go to the Config file and look for any connection string setting with the name of ApplicationServices and replace all its attributes with the ones here when the build mode is Release build. The second line means look for a setting with the key of   BaseAddress and replace all its attributes with the ones here. ( of course, you would not want to hard code id and password here, instead you want to use integrated security for database security, but you get the idea here, right?)

Okay, with all these set up, your build and deployment is just a few button clicks.

You can choose “Web Deploy” File System Deploy” or “FTP Deploy”. For my case, I use “File System Deploy” for on-promise server deployment, and I use “Web Deploy” for Azure web site deployment.  For Azure Web site deploy, all you need to do is load the Publish Profile you downloaded from Azure portal and you are all set. For different region, you just choose different Build Configuration.  



When you are doing Web publishing, the IDE is smart enough to detect the versions of the affected components and only push the components that have been changed. The preview function allow you to see what will be deployed to the site.  This greatly reduced the time spent and the risk associated with deployment process. The following is the screenshot of the preview screen.



once you are happy with the preview you see, all you need to do is click on <Publish> button. the IDE will make appropriate build based on your selection, transform the web.config file with the transformation you have and published the bits to the site. at the end of it, it will launch IE with your site opened in it. For my site, with the size of 50MB, the publishing process takes 1 to 2 minutes if it is fresh build. If it is a update build, it just takes sub-seconds. Of cause, the IDE needs to build the solution first. In my experience, I find it is better to do a “Rebuild All” before publishing would save you some time, in case the build produce problems.  



This could potentially replace the tokenization process we use if we decided to upgrade to VS 2010 or above.  Please refer to the links below for further reading on Web Configuration Transformation



http://msdn.microsoft.com/en-us/library/dd465326(v=vs.110).aspx

http://msdn.microsoft.com/en-us/library/dd465318(v=vs.100).aspx

If you are on “Standard” tier in Azure, you are offered backup restore functionality for your web site. with that I can backup your site  before deployment, and in case deployment encountered problem, you can  easily rollback to the one you had before your deployment process. From the screenshot below you can see a link with the caption of <BackUPS>



As always, feedbacks and comments on this article and suggestions on future writing are welcome.