Thứ Ba, 17 tháng 3, 2015

Top 10 thay đổi trong ASP.NET 5 và MVC 6

Bài viết được dịch từ: http://stephenwalther.com/archive/2015/02/24/top-10-changes-in-asp-net-5-and-mvc-6

Tôi đã dành vài tuần qua để viết code mẫu cho ASP.NET 5/MVC và tôi đã bị kinh ngạc bởi sự thay đổi sâu trong phiên bản beta hiện tại của ASP.NET 5. ASP.NET 5 là phiên bản mới ra mắt và quan trọng nhất của ASP.NET trong lịch sử của ASP.NET framework - nó đã được viết lại hoàn toàn từ bên dưới lên.

Trong bài viết này, tôi liệt kê những cái tôi coi là top 10 sự thay đổi quan trọng nhất trong ASP.NET 5. Đây chỉ là danh sách theo ý kiến riêng. Nếu những thay đổi khác bạn cho là quan trọng hơn, hãy mô tả nó trong phần comment.

1. ASP.NET trên OSX và Linux

Linux and OSX
Lần đầu tiên trong lịch sử ASP.NET, bạn có thể chạy ứng dụng ASP.NET 5 trên OSX và Linux. Hãy để tôi lặp lại. Ứng dụng ASP.NET 5 có thể chạy trên Windows, OSX, và Linux. Điều này mở ra cho ASP.NET 1 lượng lớn khán giả developers và designers hoàn toàn mới.
Lượng khán giả truyền thống của ASP.NET là những nhà phát triển chuyên nghiệp làm việc trong 1 công ty. Khách hàng doanh nghiệp được hàn vào những chiếc máy tính Windows của họ.
Những startup, ở chiều ngược lại, có xu hướng sử dụng OSX/Linux. Bất cứ khi nào tôi tham dự 1 hội nghị startup, tôi chỉ thấy những máy trong khán giả là Macbook Pro. Những người không phải người dùng truyền thống của ASP.NET.
Hơn nữa, những nhà thiết kế và phát triển front end, ít nhất khi họ bên ngoài nhà tù công ty cũng có xu hướng sử dụng Macbook Pro. Bất cứ khi nào tôi dự 1 hội nghị jQuery, tôi thấy Macbook Pro khắp nơi (hình dưới là từ jQuery blog).
jQuery Conference
Cho phép ASP.NET 5 chạy trên Windows, OSX, và Linux thay đổi mọi thứ. Lần đầu tiên, tất cả nhà phát triển và nhà thiết kế có thể bắt đầu xây dựng ứng dụng với ASP.NET 5. Và họ có thể sử dụng môi trường phát triển ưa thích như Sublime Text và WebStorm khi làm việc với các ứng dụng ASP.NET (Không yêu cầu Visual Studio).
Hãy tìm hiểu dự án OmniSharp để thấy bạn có thể sử dụng các trình biên tập như Sublime Text, Atom, Emacs, và Brackets với ASP.NET 5 như thế nào:

2. Không còn Web Forms

ASP.NET Unleashed
Tôi yêu ASP.NET Web Forms. Tôi đã chi trả hàng trăm, nếu không phải hàng ngàn giờ của cuộc đời mình để xây dựng ứng dụng Web Forms. Tuy nhiên, cuối cùng cũng tới lúc nói lời tạm biệt. ASP.NET Web Forms không còn là 1 phần của ASP.NET 5.

Bạn có thể tiếp tục xây dựng ứng dụng Web Forms trong Visual Studio 2015 sử dụng .NET 4.6. Tuy nhiên, ứng dụng Web Forms không thể có được những thuận lợi của những tính năng mới tuyệt vời của ASP.NET 5 được mô tả trong danh sách. Nếu bạn không muốn bị bỏ lại đằng sau khi lịch sử tiến về phía trước thì đã đến lúc bạn phải viết lại ứng dụng Web Forms của bạn thành ASP.NET MVC.

3. Không còn Visual Basic

Visual Basic
Cũng là lúc nói lời tạm biệt với Visual Basic. ASP.NET 5 chỉ hỗ trợ C# và Visual Basic bị bỏ lại đằng sau.

Tôi hy vọng rằng sự thay đổi này không trở thành nỗi đau. Tôi tin rằng chỉ có 2 người trên toàn thế giới đang xây dựng ứng dụng MVC bằng Visual Basic. Đây là lúc cả 2 bạn phải dừng lại. Có những công cụ chuyển đổi tốt cho sự di chuyển từ Visual Basic sang C#:

4. Tag Helpers

Tag Helpers là một tính năng có thể có tác động lớn nhất tới cách mà bạn tạo view trong một ứng dụng ASP.NET MVC. Tag Helpers là một thay thế tốt hơn để sử dụng MVC helpers truyền thống.

Xem xét view dưới đây có chứa 1 form để tạo 1 product mới.

@model MyProject.Models.Product
@using (Html.BeginForm())
{
    <div>
        @Html.LabelFor(m => p.Name, "Name:")
        @Html.TextBoxFor(m => p.Name)
    </div>
    <input type="submit" value="Create" />
}
Trong view phía trên Html.BeginForm(), Html.LabelFor(), và Html.TextBoxFor() được sử dụng để tạo form. Những helpers này có thể không thân thiện với lại HTML designer.

Đây là cách tương tự form có thể được tạo sử dụng Tag Helpers:

@model MyProject.Models.Product
@addtaghelper "Microsoft.AspNet.Mvc.TagHelpers"

<form asp-controller="Products" asp-action="Create" method="post">
    <div>
        <label asp-for="Name">Name:</label>
        <input asp-for="Name" />
    </div>

    <input type="submit" value="Save" />
</form>

Chú ý rằng phiên bản mới này của form chỉ chứa (cái giống như) các phần tử HTML. Ví dụ, form chứa 1 phần tử INPUT thay vì 1 Html.TextBoxFor(). Một người thiết kế front end sẽ hài lòng với trang này.

Thứ đặc biệt duy nhất về view này này là các thuộc tính đặc biệt asp-for. Các thuộc tính này được sử dụng để mở rộng các phần tử chức năng bên phía server ASP.NET MVC.
Damien Edwards gom toàn bộ các ví dụ mẫu tại đây:

5. View Components

Tạm biệt subcontroller và chào mừng View Component.

Trong phiên bản trước của ASP.NET MVC, bạn sử dụng Html.Action() để gọi 1 subcontroller. Ví dụ, tưởng tượng rằng bạn muốn hiển thị banner quảng cáo trong nhiều view. Trong trường hợp này bạn có thể tạo 1 subcontroller chứa xử lý logic, trả về 1 banner quảng cáo nào đó và gọi subcontroller bằng Html.Action() từ 1 view.

Subcontrollers - Html.Action() không được kèm trong phiên bản beta hiện tại của MVC 6. Thay vào đó MVC 6 kèm theo 1 công nghệ thay thế được gọi là View Components.

Dưới đây là bạn có thể tạo 1 View Component hiển thị 1 hoặc 2 banner quảng cáo phụ thuộc theo thời gian của ngày.

using Microsoft.AspNet.Mvc;
using System;

namespace Partials.Components
{
    public class BannerAd : ViewComponent
    {
        public IViewComponentResult Invoke()
        {
            var adText = "Buy more coffee!";

            if (DateTime.Now.Hour > 18)
            {
                adText = "Buy more warm milk!";
            }
            return View("_Advertisement", adText);
        }
    }


Nếu thời gian trước 5h chiều thì View Component trả về 1 partial gọi là _Advertisement với đoạn text là “Buy more coffee!”. Nếu sau 5h chiều thì text thay đổi thành “Buy more warm milk!”.

Nội dung _Advertisement partial như sau:
@model string

<div style="border:2px solid green;padding:15px">
    @Model
</div>

Cuối cùng bạn có thể sử dụng BannerAd View Component trong MVC view:

@Component.Invoke("BannerAd")

View Components rất tương tự subcontrollers. Tuy nhiên, subcontrollers đã luôn là một thứ gì đó kỳ quặc. Chúng giả vờ là controller action nhưng chúng không thực sự là controller action. View Componets thì có vẻ tự nhiên hơn.

6. GruntJS, NPM, và Bower Support

GruntJS

Phát triển front-end nhận được nhiều tình yêu từ ASP.NET 5 thông qua sự hỗ trợ của nó cho GruntJS.

GruntJS là 1 task runner cho phép bạn xây dựng front-end resources như JavaScripts và CSS. Ví dụ, bạn có thể sử dụng GruntJS  để nối và giảm bớt file JavaScript mỗi khi bạn thực hiện build trong Visual Studio.

Có hàng ngàn plugin của GruntJS cho phép bạn làm những nhiệm vụ tuyệt vời khác nhau (hiện có khoảng 4,334 plugins được liệt kê trong GruntJS plugin repository):

http://gruntjs.com/plugins

Ví dụ, có nhiều plugin chạy JavaScript unit test, kiểm tra chất lượng code JavaScript (jshint), biên dịch LESS và Sass file thành CSS, biên dịch TypeScript thành JavaScript, và giảm hình ảnh.

Để hỗ trợ GruntJS, Microsoft cần hỗ trợ 2 người quản lý package mới (ngoài Nuget). Trước hết, vì GruntJS plugin được phân phối như NPM package. Microsoft đã thêm hỗ trợ cho NPM package.

Thứ 2, vì nhiều client-side resources như Twitter Bootstrap, jQuery, Polymer, và AngularJS được phân phối thông qua Bower, Microsoft đã thêm hỗ trợ cho Bower.

Điều này có nghĩa là bạn có thể chạy GruntJS sử dụng plugins từ NPM và client resources từ Bower.

7. Hợp nhất MVC và Web API Controllers

Trong phiên bản trước của ASP.NET MVC, MVC controller thì khác so với Web API controller. Một MVC controller sử dụng lớp cơ sở System.Web.MVC.Controller và Web API controller sử dụng lớp cơ sở System.Web.Http.ApiController.

Trong MVC 6, chỉ có 1 và duy nhất 1 lớp controller là lớp cơ sở cho cả MVC và Web API controller. Chỉ có 1 lớp Microsoft.AspNet.Mvc.Controller.

MVC 6 controller trả về 1 IActionResult. Khi sử dụng như là 1 MVC controller, IActionResult có thể là 1 view. Khi sử dụng như là 1 Web API controller, IActionResult có thể là dữ liệu (ví dụ 1 danh sách product). Cùng controller có thể có các hành động vừa trả về view và dữ liệu.

Trong MVC 6, cả MVC controller và Web API controller sử dụng chung routes. Bạn có thể sử dụng convention-based routes hoặc attribute routes và chúng áp dụng cho toàn bộ controller trong project.

8. AngularJS

AngularJS là 1 trong những framework phía client phổ biến nhất để xây dựng Single Page Applications (SPAs). Visual Studio 2015 bao gồm các templates cho việc tạo các AngularJS modules, controllers, directives, and factories.
AngularJS
Sự hỗ trợ của ASP.NET 5 cho GruntJS làm cho ASP.NET thành 1 nền tảng server-side tuyệt vời cho việc xây dựng các ứng dụng client-side AngularJS. Bạn có thể kết hợp và giảm bớt tất cả file AngularJS của bạn một cách tự động mỗi khi bạn thực hiện build. Bạn có thể tương tác với 1 MVC 6 controller từ 1 AngularJS $resource sử dụng REST.

9. ASP.NET Dependency Injection Framework

ASP.NET 5 đã được hỗ trợ Dependency Injection và Service Locator pattern. Điều này có nghĩa là nó không còn phải dựa vào Dependency Injection frameworks bên thứ ba như Ninject hoặc AutoFac.

Tưởng tượng, ví dụ, bạn tạo 1 IRepository interface và 1 lớp EFRepository  implement interface này. Trong trường hợp này bạn có thể bind class EFRepository tới interface IRepository trong phương thức ConfigureServices() của class Startup.cs như thế này:

services.AddTransient<IRepository, EFRepository>();

Sau khi bạn bind EFRepository và IRepository thì bạn có thể sử dụng hàm tạo dependency injection trong MVC controller của bạn (và bất cứ class nào khác) sử dụng code như sau:

public class ProductsController : Controller
{
    private IRepository _repo;

    public ProductsController(IRepository repo)
    {
        _repo = repo;
    }
}

Trong đoạn code bên trên, interface IRepository được thông qua hàm tạo của ProductsController. ASP.NET Dependency Injection framework lấy EFRepository cho ProductsController vì IRepository đã được bind với EFRepository.

Bạn cũng có thể sử dụng Service Locator pattern. Khi bạn truy xuất HttpContext, bạn có thể truy xuất bất cứ các service được đăng ký. Ví dụ, bạn có thể lấy EFRepository bằng cách sử dụng đoạn code bên dưới trong 1 MVC controller action:

var repo = this.Context.ApplicationServices.GetRequiredService<IRepository>();

10. xUnit.net

Tạm biệt Visual Studio Unit Testing Framework và chào mừng xUnit.net!

Trong các phiên bản trước của ASP.NET MVC, framework testing mặc định là Visual Studio Unit Testing Framework (thỉnh thoảng được gọi là mstest). Framework này sử dụng [TestClass] và [TestMethod] attributes để mô tả 1 unit test:

[TestClass]
public class CalculatorTests {

    [TestMethod]
    public void TestAddNumbers() {
        // Arrange
        var calc = new Calculator();

        // Act
        var result = calc.AddNumbers(0, 0);

        // Assert
        Assert.AreEqual(0, result);
    }
}

ASP.NET 5 sử dụng xUnit.net như là unit test framework của nó. Framework này sử dụng [Fact] attribute thay vì [TestMethod] attribute (và không còn [TestClass] attribute]):

public class CalculatorTests
{
    [Fact]
    public void AddNumbers()
    {
        // Arrange
        var calculator = new Calculator();

        // Act
        var result = calculator.AddNumbers(1, 1);

        // Assert
        Assert.Equal(result, 13);
    }
}

Nếu bạn nhìn vào source code ASP.NET 5 thì bạn sẽ thấy rằng xUnit.net được sử dụng để test ASP.NET rộng rãi. Ví dụ, MVC repository chứa unit test được viết với xUnit.net. Bạn có thể tìm hiểu MVC repository (và unit test của nó) ở đây:

http://github.com/aspnet/mvc

ASP.NET sử dụng 1 nhánh của xUnit.net được đặt tại:

https://github.com/aspnet/xunit

Thứ Hai, 2 tháng 3, 2015

How to reverse a number using c#

Chú ý: Hàm trên chỉ chạy với trường hợp số không dấu. Tùy mục đích sử dụng cho cả số có dấu thì cần cải tiến thêm.

        public static int Reverse(int num)
        {
            int result = 0;
            while (num > 0)
            {
                //chia cho 10 lấy dư sẽ lấy lần lượt được các số từ phía sau trờ lại
                //mỗi lần lặp thì lấy kết quả * 10 lần và cộng thêm số mới lấy dư do chia cho 10
                result = result * 10 + num % 10;
                num /= 10;
            }
            return result;
        }