What is Cache Busting? What about Ctrl + F5?

Have you ever met browser caching issues that you have to ask your users to use Ctrl + F5 to fix the problem? Do you want to get rid of this user-unfriendly behavior?

There are many ways to prevent this issue from happening. I just mention the promising three here [3].

  • File name versioning (e.g. style.v2.css).
  • File path versioning (e.g. /v2/style.css)
  • Query strings (e.g. style.css?ver=2). It is probably adequate because Stackoverflow currently uses this technique, and there are millions of Stackoverflow users [1]. But some authors point out it doesn’t always work [4]

File name versioning and file path versions, by theory, will always work.

Our life can become much easier if we just let the framework to do the job.

If you use asp.net MVC 5, you are lucky because it’s built in with bundling feature. In addition, the bundle path points to a virtual path, and makes it easy to change this virtual path.

public static void RegisterBundles(BundleCollection bundles)
{
    string version = "{version}"; // version from app settings, etc
    bundles.Add(new ScriptBundle("~/bundles/ABC-" + version)
           .Include("~/Scripts/ABC1.js",
                    "~/Scripts/ABC2.js",
                    "~/Scripts/ABC3.js"));

    // Code removed for clarity.
    BundleTable.EnableOptimizations = true;
}

For how to use MVC 5 bundling feature in details, please refer to Bundling and Minification [9].

Background: I talked to Mike, a front-end expert. He mentioned there was a term for fighting these unwanted browser caching behavior, and the term is call “Cache Busting”. I used to search using the keywords such as “clean browser caches”. Now I can search by “cache busting” instead.

By the way, the approach of cleaning browser caches programmatically using Javascript is a dead-end road because of security concerns that browsers will never allow you to do so. [6]

References:

  1. https://stackoverflow.com/questions/9692665/cache-busting-via-params
  2. http://www.adopsinsider.com/ad-ops-basics/what-is-a-cache-buster-and-how-does-it-work/
  3. https://www.keycdn.com/support/what-is-cache-busting/
  4. https://css-tricks.com/strategies-for-cache-busting-css/
  5. https://stackoverflow.com/questions/8155064/how-to-programmatically-empty-browser-cache
  6. https://www.quora.com/Is-there-a-method-to-program-an-automatic-clearing-of-a-browser-cache-in-JavaScript
  7. https://www.aspsnippets.com/Articles/Using-Bundles-ScriptBundle-in-ASPNet-MVC-Razor.aspx
  8. https://stackoverflow.com/questions/11979718/how-can-i-specify-an-explicit-scriptbundle-include-order
  9. https://docs.microsoft.com/en-us/aspnet/mvc/overview/performance/bundling-and-minification
  10. http://www.tutorialsteacher.com/mvc/scriptbundle-mvc
  11. http://www.c-sharpcorner.com/article/bundling-in-asp-net-mvc-application/
Advertisements

Expressive Power of JavaScript In Implementing Visitor Pattern

Implementing the Visitor Pattern using JavaScript for fun during this weekend.

According to GOF [1], visitor pattern is:

“Represent an operation to be performed on elements of an object structure. Visitor lets you define a new operation without changing the classes of the elements on which it operates.”

There are three key components when using visitor pattern:

  1. Element hierarchy, and
  2. Visitors, and
  3. Clients that use element hierarchy and visitors.

In my implementation, I have:

  1. Element hierarchy. abstract employee, full time and part time concrete employees
  2. Visitors. totalAmountSalaryVisitor, totalAmountPartTimeVisitor, averageCompensationVisitor
  3. Clients. Creates employees, add visitors, and get the results.

JavaScript is very expressive. If you want to add a ‘accept’ function to the employees array, you just add it. You don’t need to use a wrapper or extension method like class-oriented languages.

var employees = [];
employees.accept = function(visitor) { 
  this.forEach(function(element) {
    element.accept(visitor);
  });
};

Adding ‘accept’ method to the abstract employee just as simple.

var employee = function(spec) {
  var that = {};
  that.firstName = spec.firstName || "*";
  that.lastName = spec.lastName || "*";
  that.age = spec.age || 0;
  that.employmentType = spec.employmentType || "Employee"; 
  that.accept = function(visitor) {
    visitor.visit(that);
  };
  return that;
}

 

JavaScript is also class-free. You can just create visitor anytime and in any shape you want as long as it has a ‘visit’ method.

var totalAmountSalaryVisitor = {
  total: 0,
  visit: function(fullTimeEmployee) {
    this.total += fullTimeEmployee.salary || 0;
  }
};

Compared to the similar implementation in C# [5], the JavaScript version is more nature and more expressive, requires much less lines of codes, and, most importantly, more fun!

Full source code: https://thimbleprojects.org/yellowship/418220/ (You have to click the ‘Remix’ button on the right top corner to see the source code.)

References:

  1. Erich Gamma, Richard Helm, Ralph Johnson, John Vlissides (1994). Design Patterns: Elements of Reusable Object-Oriented Software. Addison Wesley.  ISBN  0-201-63361-2
  2. https://en.wikipedia.org/wiki/Visitor_pattern
  3. https://sourcemaking.com/design_patterns/visitor
  4. http://www.oodesign.com/visitor-pattern.html
  5. http://www.dofactory.com/net/visitor-design-pattern

 

 

 

A Review of Murach’s PHP and MySQL (3rd edition)

 

The combination of PHP, MySQL, and Linus has been very popular among open-source web developers for almost 20 years now. I used this powerful combination around 2000, and later moved on to .net, Oracle, and SQL server due to the changes of jobs. Fast forward 13 years, around 2013, one of my friends decided to jump on the wagon of PHP and MySQL from .net shop. He said there were more remote opportunities in PHP and MySQL world, and there were latest features such as MVC pattern and objects in PHP as well.

The book begins with introductory text on PHP and MySQL, and builds a simple website using MVC pattern. Then the content is divided into two threads. The first thread dives deep into mastering PHP. It covers functions, objects, etc. The second thread focuses on MySQL programming including basic database design concepts. These two threads then merges into the most exciting final chapters in my opinion, real-world e-commerce website embedded a content / image management sub-system.

I think this book covers more than enough topics on both PHP and MySQL to kick start your learning experience if you just begin. You should follow along the examples in the book and do the exercises. The learning experience is quite rewarding because we are going to learn the following systems and tooling, PHP / MySQL (of course), NetBean IDE, Xdebug, XAMPP Control Panel, MySQL work bench, etc. For more experienced developers, this book can be a desktop reference or a fun read. I highly recommend this book.

The book review was first posted at Amazon.

 

 

C# Extension Method vs Instance Method, and JavaScript Equivalent

C# extension method gives us the illusion of adding an instance method on a 3rd party class.

While worked on adding extension methods to WEB API controller, I felt these extension methods cannot do too much without accessing controller’s instance methods. So I switched to inheritance. BaseApiController<T> was inherited from ApiController, and I also added template methods and function objects to achieve what I wanted to do.

So when do we use extension method and when do we use instance method?

Extension Method Instance Method
Inheritance No Yes
Add to base class without notice Yes No
Can access objects’ internals No Yes
Create a new type No Yes
Scope namespace with inheritance tree
Design pattern similarity Decorator (add new behavior with modifying the base class)
Extend sealed class Yes No

Another interesting observation is that in Javascript, we can add a method to an object directly to do the same thing without extension method and instance method. So in my personal opinion, JavaScript is more expressive than C# if we know what we are doing.

 

References:

  1. https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/extension-methods
  2. https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/how-to-implement-and-call-a-custom-extension-method

 

Read Request Content in Web API

In some scenarios, we must read the http request content as string, and parse the string ourselves.

public IHttpActionResult POST() 
{        
     string requestContent = ReadRequestContent(Request).Result;        
     return OK(requestContent);
}
private async Task<string> ReadRequestContentAsync(
                               HttpRequestMessage Request)
{        
     string result = await Request.Content.ReadAsStringAsync();        
     return result; 
}

 

References:

  1. https://docs.microsoft.com/en-us/aspnet/web-api/overview/getting-started-with-aspnet-web-api/action-results
  2. https://weblog.west-wind.com/posts/2013/dec/13/accepting-raw-request-body-content-with-aspnet-web-api?Page=2

Customize IHttpActionResult in WEP API 2

According to [1], some advantages of using the IHttpActionResult interface are:

  1. Simplifies unit testing your controllers.
  2. Moves common logic for creating HTTP responses into separate classes.
  3. Makes the intent of the controller action clearer, by hiding the low-level details of constructing the response.

Today, we are going to customize IHttpActionResult to create a class VersionedTextResult to support API versioning based on TextResult in [1].

public class VersionedTextResult : IHttpActionResult
{
    string _value;
    string _version;
    HttpRequestMessage _request;

    public TextResult(string value, string version, 
			HttpRequestMessage request)
    {
        _value = value;
        _version = version;
        _request = request;
    }

    public Task<HttpResponseMessage> ExecuteAsync(
        CancellationToken cancellationToken)
    {
        var response = new HttpResponseMessage()
        {
            Content = new StringContent(_value),
            RequestMessage = _request
        };
        var responseHeadersContentType = 
            response.Content.Headers.ContentType; 
        NameValueHeaderValue versionParamter = 
            new NameValueHeaderValue("version", Version);
        responseHeadersContentType.Parameters.Add(versionParamter);
        return Task.FromResult(response);
    }
}

 

References:

  1. https://docs.microsoft.com/en-us/aspnet/web-api/overview/getting-started-with-aspnet-web-api/action-results
  2. https://docs.microsoft.com/en-us/aspnet/web-api/overview/testing-and-debugging/unit-testing-controllers-in-web-api

C# Async and Await Revisit

In my last post about async and Await, I forgot to mention to use Task<TResult>.Result to pause the control flow and get the results immediately. In these code blocks, I showed two locations to use Task<TResult>.Result, and location 2 is the preferred location since we are taking advantage of async programming.

 

static void Main(string[] args)
{
  Console.WriteLine("Main ThreadId: "
    + Thread.CurrentThread.ManagedThreadId + ", start" + "\r\n");

  AsyncAwaitTest aa = new AsyncAwaitTest();
  Task<int>[] tasks = new Task<int>[5];
  for (int i = 1; i <=5; i++)
  {
    tasks[i-1] = aa.GetStringAsync(i);
    // Location 1
    // If we uncomment the following line, it will force the program 
    // to sync mode and get the result immediately 
    // Console.WriteLine("Task : " + i + ": " + tasks[i - 1].Result);
  }

  Console.WriteLine("Main ThreadId: " 
    + Thread.CurrentThread.ManagedThreadId 
    + ", control back (UI responsive)." + "\r\n");

    for (int i = 1; i <=5; i++) 
    { 
        // Location 2
        // The preferred location 
        // since we are taking advantage of async programmin
        Console.WriteLine("Task : " + i + ": " + tasks[i - 1].Result); 
    } 

  Console.ReadKey();
}
public class AsyncAwaitTest
{
  public async Task GetStringAsync(int workerNumber)
  {
    Console.WriteLine("Worker #" + workerNumber + ", ThreadId: "
      + Thread.CurrentThread.ManagedThreadId
      + ", begin to process tons of data here ... ");
    var httpClient = new HttpClient();
    Task getStringAsync = 
    httpClient.GetStringAsync("http://msdn.microsoft.com");
    string content = await getStringAsync;
    int length = content.Length;
    Console.WriteLine("Worker #" + workerNumber + ", ThreadId: "
      + Thread.CurrentThread.ManagedThreadId + ", finished");
    return length;
  } 
}

Dependency Injection Tip: Swap Runtime Environments

We design our apps with design principles and best practices. The resulting apps usually have dependency injection in place already. We then can use Ninject as the dependency injection tool, and set up in-memory test objects along with our production codes.

The question is that how can we click a button to swap the in-memory test environment and debug/release environment easily?

Luckily, there are  two features in Visual Studio, build configuration and conditional compilation, which can solve our problem easily.

  1. In VS solution, create a new build configuration, InMemory, and choose to inherit the setting from Debug.
  2. Add a constant ‘INMEMORY’ to the ‘Conditional compilation symbols’ in the ‘Build’ tab of project property.
  3. Add conditional compilation in Ninject’s Register Services code block

 

/// <summary>
/// Load your modules or register your services here!
/// </summary>
/// <param name=”kernel”>The kernel.</param>
private static void RegisterServices(IKernel kernel)
{
#if INMEMORY
kernel.Bind<IYourInterface>().To<YourInMemoryImplementation>();
#else
kernel.Bind<IYourInterface>().To<YourDebugReleaseImplementation>();
#endif
}

Git: What it is in 5 minutes

Tags

Git is a light-weight distribution version control system.

Git is built on 4 layers of abstractions like an onion, and each layer is based on another.

  1. Persistent map. The technical cornerstone is SHA1, a hashing algorithm.
  2. Content tracker
  3. Version control
  4. Distribute version control

A few things worth noting technically.

  1. Git is path independent because it is based on persistent maps.
  2. It is inherently easy to understand. It only has four types of objects, blob, tree, comment, tag.
  3. A branch is just a commit. This idea really blew me away because I never think from this perspective. Branching is super easy to understand.
  4. A commit is a snapshot of the persistent map.
  5. Rebase. Nice concept if used correctly
  6. Good fit for distributed peers like open source projects

 

References:

  1. Paolo Perrotta, How Git Works, Pluralsight
  2. https://docs.microsoft.com/en-us/vsts/tfvc/comparison-git-tfvc
  3. https://www.petri.com/team-foundation-version-control-verses-git-visual-studio-team-services

Microsoft Azure: Stack, Private, Public, Hybrid

There are Azure Stack, Private/Public/Hybrid Cloud in In Microsoft Azure.

Private Cloud: Azure on premise. An enterprise has to keep some apps and data on premise by regulations.

Public Cloud: Cloud hosted by Microsoft.

Hybrid Cloud: An enterprise uses both private and public cloud.

Azure Stack: in fact, it’s a private cloud. All the VMs, containers, app services, etc., are compatible and transferable seamlessly to public cloud if needed.