Which JavaScript framework should I choose in the Enterprise?

July 16, 2017

There are various reasons that modern application developers should be using JavaScript frameworks when developing new applications. The modern browser has become almost a complete application hosting environment runtime. The added responsiveness, the performance, the ability to easily asynchronously request and manipulate data, to build different parts of your page progressively and independently, are only some of the benefits. If you’re going to choose to build an application in the browser, you need structure, you need to deliver features quickly, you need them to perform and you need to provide consistency.

JavaScript alone does not provide this. JavaScript doesn’t provide structure, it doesn’t provide custom UI elements, it doesn’t provide data binding or animations and it doesn’t provide a network communication framework. Everything in JavaScript is done with add-ons, and the time taken to build your own libraries can be prohibitive and a hindrance to actually delivering your own custom application logic.

Even Gartner says that you should be using a JavaScript framework. Gartner’s Research Director Bradley Daley says that 40% of companies are now using JavaScript frameworks heavily in their projects.

But we need to be careful here. It’s very easy to be swept up in hype. It seems to be a systemic problem in the industry that we have a tendency to jump into new technological choices far too quickly. Don’t be swayed or swept up by the hype.

But there are so many JavaScript frameworks! So which framework should you choose, and what are the criteria you should be looking at?

When selecting a JavaScript framework for the Enterprise, there are a number of factors you really need to consider. These include:

1)     Adoption – Does it have the backing of industry leaders? Who is behind it? Who is using it? How many production deployments are there? Is there community and developer support? Are there many jobs for it? Can I get the developers I need?

2)     Opinionated – does it provide you with a ready-made framework where most of the basic structural problems already have solutions, or do you need to put those solutions together yourself?

3)     Learning curve – How hard is it to learn and is it worth the effort to do so?

4)     Future proof – will this framework be around for a while? Is it using web standards and does it have a path towards future web standards? Is there a roadmap for supporting future web standards?

5)     Feature richness – Can I build awesome sites with it?

6)     Productivity – How easy is it to add features? How easy is it to maintain?

7)     Testable – is there a strategy for testing the application components?

8)     Size – does the framework contain a lot of large files? Is it slow to download? Is it heavy?

9)     Performance – does the framework introduce impediments to performance?

10)  Browser support – does the framework support many browsers including older versions?

11)  Licensing – are there any gotchas?

Adoption

There are only a few JavaScript frameworks that have made it really big. The two biggest are Angular and React. Angular is backed by Google, while React is backed by Facebook. Angular version 1 (AngularJS) was one of the most widespread technologies in use for an exceptionally long time. In fact, the earliest issue on the AngularJS wiki was raised in 2011 and its adoption was about 5 times bigger than React at the time it was deprecated. At the time of writing, Angular version 1 had 56,400 stars on GitHub. That’s a popular base.

But you wouldn’t start a new project in Angular version 1. There is virtually no one recommending people take that path. Bradley Dayley from Gartner certainly doesn’t recommend it, saying “Angular 2 is a much better option than Angular 1” and “Angular 2 is still one of the better frameworks out there”. Rob Eisenberg from Aurelia (and now Microsoft) doesn’t recommend it. Angular 1 has structural problems that cannot be discounted. If you’re on Angular 1, you really need to move forward. Jeremy Likeness, Director of Application Development at iVision made the comment “There will continue to be a long tail for Angular 1 apps, but there is a clear path to Angular 2 and I see people taking that path.”

Angular version 2 (now known as the singular “Angular” and currently at version 4) is a complete rewrite of Angular version 1. It was given the same significant support that Angular 1 was given. Google has backed it all the way, and, in fact, they have completely rewritten Google AdWords with it. That’s over a million lines of code. Angular 2 was started in 2015, and it now has 25,900 stars on GitHub. And according to Bradley Dayley, “Angular 2 is still one of the better frameworks out there.”

React, on the other hand, has grown significantly. React is used by Facebook on Facebook. It currently has 71,033 stars on GitHub and has been around since 2013. Up until the Angular 1 rewrite was announced, it was making reasonable progress, but after the Angular 1 announcement, its popularity shot up as it was the main beneficiary of the doubts around Angular. People say you can’t compare the two, but that’s rubbish. The reality is that you can compare the two, because to use React you will pull in a Router, a Flux implementation, and various libraries. You will build a framework to provide the same functionality that you get from Angular. React probably has the strongest developer advocacy of any of the JavaScript frameworks.

Then, of course, there are other libraries. Backbone and Knockout are on the way out. Aurelia just hasn’t got the take-up, although it certainly has the support of its developers. Polymer is just meh at the moment. Meteor is a bit too rigid and doesn’t have the take-up.

Probably the biggest contender at the moment is VueJs. It’s new and the fastest growing of all the frameworks. It has 60,100 stars on GitHub already, and it’s only been around since 2015. It’s just like React, though, and will require you to put together a whole framework.

In terms of trends, in the last month, Angular 2 has grown by 1016 stars, React has grown by 2,495 stars, but Vue has grown by a staggering 3,546 stars!

For now, though, in the Enterprise, I’d probably say no to VueJs, for now, but it’s certainly worth keeping an eye on and revisit in a year or so.

Because of these factors, in this article, I will focus on the two biggest players in the space, React and Angular.

Opinionated

Probably the biggest argument for and against the frameworks is whether or not they are opinionated. An opinionated framework is prescriptive; It is one where the majority of the structural/infrastructure decisions have been made for you. That is, it provides prebuilt boilerplate code that forces you to structure your code in a particular way. And because a lot of those decisions have been made for you, you can get on and focus on your own custom code, rather than having to work on building up the framework, spending a ridiculous amount of time building the infrastructure before you even get to write your first line of business-related custom application code. Sure, it might be a technically brilliant solution, but apart from some nerd points, who really cares?

Angular 2 is an opinionated framework. Out of the box, you have pretty much everything you need to build an Enterprise application. React, on the other hand, has so few strong opinions. To build something Enterprise ready requires a significant number of decisions. You need to build a foundation. These days, React provides a Router (it never used to) and you need to select one of the 20+ variations of Flux, but you should probably choose the most popular, being Redux. You’ll also need to select an interaction library to get you data from an external repository, something like Thunk. In fact, I would say that React, to me, requires a dog’s breakfast of technologies just to get a foundation up and running. And with putting together such a mix of new technologies, some will be more mature than others, and many are not actually supported by FaceBook.

So of course, it can be done, and many people are doing it. Between the time when Angular 1 was deprecated and Angular 2 was just getting off the ground, that’s what people were doing, as they didn’t really have another choice, and people were quite angry at what was happening to Angular.

If you’re going down the path of React, I would recommend going with all the most popular versions of the React tech stack. Here I recommend that you do a Pluralsight course and put together a framework based on what you learn from that, and build on that learning.

So, in the case of choosing a JavaScript Framework that has everything you need to build an Enterprise application, with all the modules supported, I would have to say Angular 2 wins hands down.

Learning curve

JavaScript frameworks are not the easiest to learn. Both Angular and React require a significant amount of time to get to an intermediate level, which would allow you to build an Enterprise application. I know there are people out there that claim it will take them a few minutes to get going with React and take far longer to learn Angular, but they’re not really talking about learning the full framework. With React, they are usually just talking about how quick they can learn how to use the view layer.

If you want to do something significant and Enterprise ready, my advice is to immerse yourself in a Pluralsight course. Make your entire team do it.

To give you an example of how long it takes to realistically learn Angular vs React, I suggest that you would need to do both a Beginner and an Intermediate course.

Doing John Papa’s Angular: First Look Beginner’s course takes 4.5 hours. Following up with Joe Eames Angular Fundamentals Intermediate course will take a further 10 hours.  That’s a 14.5-hour investment.

Doing Cory House’s Building Applications with React and Flux Beginner’s course will take around 5 hours. Following up with Cory House’s Building Applications with React and Redux in ES6 Intermediate course will take a further 6.25 hrs. That’s 11.25 hours.

So, when people tell you React is easier to learn than Angular, my response to them is, not in the Enterprise it’s not!  There’s not that much difference between 11.25 hours and 14.5 hours. If you are learning these frameworks from scratch, the investment in these courses is well worth it. You will get significant productivity benefits in doing this from day one. One gotcha here though – to learn a 10-hour course does not take 10 hours. It takes significantly longer to learn and absorb everything from one of those courses. When I started doing those courses, I found it could sometimes take me a whole day to get through one hour of course!

Future proof

We are now past the Angular 1 to 2 hiccup, and both Angular 2 and React will be around for a long time. Here, you need to ask how much each of these frameworks is oriented towards future web standards. In the case of Angular, it is closer to the web standard. React, on the other hand, diverges from web standards and patterns, and that is risky. That’s because they do their own virtual DOM code compilation, which is seen as a benefit in the case of React. Some people say that it would make it more difficult to move away from that towards a different framework that conforms better with the standard, but let’s be serious here, no one ever changes once they’ve decided on the framework until they are ready to completely rebuild the application, and an application’s lifetime is around 5 years, so it won’t be happening for some time.

Productivity

I have written apps in React and Angular and I have yet to form an opinion on this one. I rewrote an entire C# MVC web app in Angular 2 recently, it took me 2 weeks (just about killed me), but I was able to do it efficiently, and once the patterns were in place, it was pretty easy to cut and paste, and add features.

Also, I am actually more impressed with the separation of html from code, which Angular provides. Because of the way React works, the code and the html are all in one file. They say this is a good thing, but I believe that keeping the UI as separate as possible from the code is better, especially if you have designers on the team, who might want to modify the layout of the html while you are still coding the component.

Feature richness

Both Angular and React are feature rich and there is support for a massive number of add-ons for both environments.

Size

I found it exceptionally hard to verify the claims that React is significantly smaller than Angular. Anton Vynogradenko produced a site that showed some stats obtained from a CDN for various JavaScript framework configurations. They showed that Angular 2 minimised would take 566K out of the box, whereas React with React DOM, Redux and React Router is around 191K. That’s a significant difference, and React would win hands down.

Here’s a link to Anton’s page: https://gist.github.com/Restuta/cda69e50a853aa64912d

The issue with size comes back to how long it takes to transfer the file, and for a large site with significant traffic, it would probably affect data cost as well.

Unfortunately, the stats haven’t been kept up to date, and there is no CDN provided for Angular 2 version 4. Given that Angular 4 was an optimisation release, it would surprise me considerably if the difference was still that great. Without further investigation, I can only form the opinion that React is probably about 1/3rd of the file size. In a corporate environment, it probably wouldn’t matter much, as you’d just wait the extra second for the page to load, put on a significant public site you might want to investigate this more thoroughly.

Performance

It’s hard to judge performance when all you’ve got to go on is other people’s potentially biased and vested opinions. I don’t need to give you too much of my own opinion here, other than to suggest that you take a look at Stefan Krause’s JavaScript Framework Benchmark site. This site contains a whole lot of benchmark tests for a wide array of JavaScript Frameworks, and he provides a calculated score (slowdown geometric mean) for framework speed. The benchmark was up to Round 6 at time of writing.

According to that site, Angular 2 (version 4) gets a speed score of 1.31 at its most efficient, and React with Redux gets a score of 1.41 at its most efficient. Certainly not enough to make a decision one way or the other.

In terms of memory performance, Angular 2 (version 4) and React (with Redux) are also very close. After adding 1000 rows, Angular 2 (v4) uses around 10.88 MB, while React with Redux uses 10.76 MB

Stefan’s site is here: http://www.stefankrause.net/js-frameworks-benchmark6/webdriver-ts/table.html

Browser support

Both Angular 2 and React take advantage of polyfills. Polyfills are JavaScript libraries that provide backward compatibility with older browsers.  But seriously, any organisation that is still on IE9 really should have its head checked.  Either way, transpilers these days are exceptional and you should be able to find a solution to produce what you need for either Angular or React.

Maintainability

I don’t really see much difference in the time taken to maintain React or Angular 2. Both environments are similarly componentised, so shouldn’t be a problem to maintain.

Testable

Both Angular 2 and React have a similar testing setup. I don’t see much difference here.

Licensing

Angular 2 is released under the MIT licence. You can use it pretty much however you like. You can modify it. You can on-sell it.

React is released under a modified BSD licence. The “FaceBook” licence. There is an odd clause in the FaceBook licence. Basically, there’s a non-compete clause in there. I don’t want to interpret it for you, but you should take a look yourself if you think you might have an issue. Here is the text:

“The license granted hereunder will terminate, automatically and without notice, if you (or any of your subsidiaries, corporate affiliates or agents) initiate directly or indirectly, or take a direct financial interest in, any Patent Assertion: (i) against Facebook or any of its subsidiaries or corporate affiliates, (ii) against any party if such Patent Assertion arises in whole or in part from any software, technology, product or service of Facebook or any of its subsidiaries or corporate affiliates, or (iii) against any party relating to the Software.”

Conclusion

There are a whole lot of reasons why you might choose one of these frameworks over the other, and I hope I have provided you with a few more issues to consider. If your application is small, or you want a more traditional application with only a JavaScript-based view, you might straight away choose React, or even Vue. In small applications, it probably doesn’t really matter.

If you’re building a large application and you have a highly sophisticated team that enjoys investigating and evaluating new technologies, are happy to make the specialised decisions and put in the hard work required to build a foundation, and you’re not worried about the patent clause, then by all means, go with React. But if you’re writing a large application and you need the enforced structure out of the box, I would recommend that you go with Angular.


Angular 1 is dead. Where to now?

August 7, 2016

Angular 1 has a massive market. It is by far the most widely used JavaScript framework available. It is a very opinionated framework, it has declarative power, and developers tend to lean towards the MV* patterns which has a whole lot of benefits and with which they are familiar with. So Angular itself is not going away any time soon.

The biggest problem with Angular 1 is that it is no longer being actively maintained. The main reasons for this are Componentisation, Performance and an inability to play well with search engines (SEO), which, incidently, are the main factors that have made its main competitor, React, so popular. There is also quite a significant learning curve with Angular.

Componentisation enables you to build custom component trees quite easily, and the resulting code is usually much more maintainable. Performance was always a killer in Angular 1 due to watches and the digest cycle, which was basically a system for monitoring every single changing item on your page.

There was a limit of 2000 watches, and as soon as you went over that, IE pages simply ground to a halt. Finally, having a whole lot of script on the page did not make Search Engine Optimisation easy at all. Search engines don’t know what to look at with a single page application. They find it hard to walk the tree of links between your pages, because they aren’t seeing what you are seeing, they need to interpret the script behind the scenes that is being executed.

So the Angular team announced a complete rewrite of Angular 1, because they found that the structural problems with Angular 1 could not be resolved via a simple upgrade. They gave their own existing product a resounding fail. In doing so, they signed its death warrant.

What do you select then, if you have a whole lot of experience in Angular 1, and need to choose a JavaScript framework for your next project?

Well, after analysing the market, reading a whole stack of analysis and reviews, having a play around with the technologies, I can say that there’s not a lot in it. Because Angular 2 is so different to Angular 1, you don’t need to automatically choose Angular 2 going forward. That said, because of the strength and size of the Angular 1 market, I don’t see Angular 2 going away any time soon.It may be an easier sell to management, especially how much was previously invested in Angular 1 training, to go to Angular 2.

Steve Sanderson, from Microsoft, produced the following table, showing the benefits of the few of the frameworks. I really thing the server side pre-rendering is important, especially when one of the major complaints with Angular 1 was the lack of deep-linking and SEO support.

Angular 2 Knockout React React + Redux
Language TypeScript TypeScript TypeScript TypeScript
Build/loader [1] Webpack Webpack Webpack Webpack
Client-side navigation Yes Yes Yes Yes
Dev middleware [2] Yes Yes Yes Yes
Hot module replacement [3] Yes, limited Yes, limited Yes, awesome Yes, awesome
Server-side prerendering [4] Yes No No Yes
Lazy-loading [5] No Yes No No
Efficient prod builds [6] Yes Yes Yes Yes

There is one framework not shown here that has gained some traction in recent times and that is Aurelia, which has recently been released (RTM). Aurelia was created by the developer who produced Durandal. He later joined the Angular 2 team, had some input into that, but later left that team because he disagreed with some of their decisions. And some of those decisions are probably valid, while others may not have been, such are the egos of developers. Aurelia is supposed to have a more simplified syntax to Angular but doesn’t currently have the market penetration.

I like to keep things simple. I like to look at what has solid traction, and try to limit my choices based on what the technical capabilities are, maintainability, performance, ease of learning it and popularity. This tells me that the two frameworks with the most promise are actually Angular 2 and React+Redux.

Although Angular 2 has only reached RC4, I still consider it a viable choice today, as, remember, by the time  your app is released it will most likely have gone to RTM. There are actually a number of significant applications that have been built in Angular2 release candidate. The strong tooling and support when Angular 2 is finally released is also a consideration, as whatever your choice is, you really will want longevity of your code base, and you certainly don’t want to be embarrassed by making a fringe choice that has potential that never materialises.

Alternatively, you might choose to go with React+Redux, which is also available with Visual Core 1.0 and Visual Studio 2015. React is supported by Facebook, and is part of a more advanced ecosystem. Facebook are also innovating faster to answer any architectural issues related to component-based frameworks. Each framework tries to steal the best bits from each other, and both React and Angular have been doing this.

If it was pure performance I was after, I think I would have to go with React. React is not an Angular killer, however, mainly because of the size of the Angular base and the structure it provides.  React is probably a lot simpler to learn, while Angular 2 has become better at this. It really comes down to how structured you need your code to be versus how much performance you need to get out of your web servers. With massive cloud based sites, extra web servers and lower serving capacity costs money, so I’d say they’d probably be better with React.

 

Edit: I just found another table that is worth linking to, by Shannon Duncan. It has more attributes compared, which make it much more interesting:

angular2-vs-react

That article may be found here: Angular2 vs React


Installing Angular 2 to run with Visual Core 1.0 in Visual Studio 2015

August 7, 2016

I initially had a lot of trouble even finding references to people using Angular 2 in Visual Studio 2015. It seems that no matter what I fiddled with, there were failures at every turn. It ended up being quite tricky to get it working. In the end I found that the best way to get going in Visual Studio 2015 was to use yeoman to create your base. And then work backwards to figure out where I went wrong.

Yeoman is yet another package manager. Basically, smart people put together packages with technologies that they think are right together, and submit the packages to yeoman. You go to yeoman.io and you can look up the packages that others have put together.

I initially tried via the yeoman web site, clicked on Discovering Generators, then searched for Angular2, and found the aspnetcore-angular2 package. It was ok, but I had trouble getting it working with ES5.

I recently went to NDC Sydney, and saw a session by Steve Sanderson. He has put together a great yeoman package that works with Visual Core 1.0 in Visual Studio 2015. The package is called generator-aspnetcore-spa, and installation details are available from his web site: Steve Sanderson’s blog. It has been updated to RC4, and the TypeScript target is set to es5, so it will run on most popular modern browsers.

The beauty of Steve Sanderson’s package is that it also supports React as well, in case you want to give that a try.


Why you should (almost) always choose an off-the-shelf grid and not build your own.

July 30, 2016

Recently I was in a situation with a whole lot of people who I think should know better. We were building an application and I was not there when the questionable decision was made to build their own grid.

There are a whole swag of reasons, except in the simplest of cases, why you should never build your own grid. Grids can be complicated, and they can require a significant investment to obtain even the simplest of features that you would otherwise get in an off-the-shelf product.

Features like sorting, filtering, frozen columns, frozen rows, summing, hierarchies, cell editing, data exporting, pagination etc. For high volume data, they also include virtual paging, which loads data into the grid page by page, instead of all at once. They can be styled however you want them, and they are fully tested. Sure, they can require a little bit of learning to achieve what you need, but the cost of doing this is significantly less than the build your own solution. The only time you run into problems is when there is too much bloat, or you are trying to do too much with the grid, a problem you would probably have regardless of which path you took.

But you don’t need to believe my opinion. It is a principle of Domain Driven Design. Eric Evans, the original author of Domain Driven Design has a Domain Driven Design Navigation Map which clearly states “Avoid over-investing in generic sub-domains.”

A grid is a perfect example of a generic sub-domain. From Eric’s Diagram:

domain driven design navigation map - generic subdomain

So next time someone is absolutely adamant that they need to build their own grid, see through that for what it is, especially if they claim to be Domain Driven Design experts.


Notes from building a first ASP.Net Core App (part 10)

July 25, 2016

There’s a new feature called Tag Helpers. They are attributes that you add that help clean up the html tags. They are actually executed just like yellow code, on the server. I’m going to set up a simple one to show redirection to a separate page.

  1. In the Home folder, add a new MVC View Page called Detail.cshtml. This will simply display the details for a single Hotel. Add the following code:
    @model MyFirstAspNetCoreApp.Models.Hotel
    
    <html>
    <head>
        <title>Home</title>
    </head>
    <body>
    <h1>Welcome!</h1>
        @Model.Id <br/>
        @Model.DisplayName
    </body>
    </html>
    
  2. Now we need to add a method to the Home Controller so that knows about the Detail page. In the Home Controller, add the Detail method, as follows:
    using Microsoft.AspNetCore.Mvc;
    using MyFirstAspNetCoreApp.Services;
    using System.Linq;
    
    namespace MyFirstAspNetCoreApp.Controllers
    {
        public class HomeController : Controller
        {
            private IHotelDataService hotelData;
    
            public HomeController(IHotelDataService hotelData)
            {
                this.hotelData = hotelData;
            }
            public IActionResult Index()
            {
                var model = hotelData.GetAll();
                return View(model);
            }
    
            public IActionResult Detail(int id)
            {
                var model = hotelData.GetAll().First(h => h.Id == id);
                return View(model);
            }
    
        }
    }
    

    Note that I’ve cheated a little with the use of First in the LINQ above. It’s a sample app and I need to keep it as simple as possible.

  3. Next we need to add a Tag Helper dependency to our project. Right-click on references and select the Nuget Package Manager. Choose browse and in the search box type TagHelpers. Select the Microsoft.AspNetCode.Mvc.TagHelpers package, install the latest version and blindly accept the licence. After installing the package, there will now be an extra dependency in the project.json file for the newly installed package.
  4. There is a new type of file you can use in Asp.Net now called a View Imports file. That file is called _ViewImports.cshtml. You can add import statements to that file and they will be imported by every file in that folder or in any subfolders. Right-click on the Views folder, and add a new MVC View Imports Page called _ViewImports.cshtml (the default.)
  5. Inside the _ViewImports.cshtml file I add the following line of code, which tells the application that I will be using all the tags in the current assembly:
    @addTagHelper "*, Microsoft.AspNetCore.Mvc.TagHelpers"
    
  6. Now, to keep things simple, I am going to change the DisplayName being presented in the Home Index.cshtml page to a link. In the Home Index.cshtml, I change the contents of the li tag as follows:

    @model IEnumerable<MyFirstAspNetCoreApp.Models.Hotel>
    
    <html>
    <head>
        <title>Home</title>
    </head>
    <body>
        <h1>Welcome!</h1>
        <ul>
            @foreach (var hotel in Model)
            {
            <li>
                <a asp-controller="Home" asp-action="Detail" asp-route-id="@hotel.Id">@hotel.DisplayName</a>
            </li>
            }
        </ul>
    </body>
    </html>
    

    Interestingly, you don’t actually need to specify the asp-controller tag if that’s the controller you are currently in. Also, this doesn’t mean that the old ActionLink methods aren’t still available. The following line would still work, it just doesn’t look as aesthetically appealing:

    @Html.ActionLink(@Model.Id.ToString(), "Detail", new { id = Model.Id })
    
  7. Run the application (F5) and when you hover over the links, you should see the last argument (id) change in the link. Click on one of the links, and you should see the details of that link displayed on the Detail page.

Notes from building a first ASP.Net Core App (part 9)

July 24, 2016

I now want to connect my application to the database. The Entity Framework has been completely re-written for Dot Net Core. Larger ORMs such as Entity Framework and nHibernate are great ideas, especially with their integration with LINQ, because they allows you to write SQL-like syntax in your middle-tier, instead of manipulating SQL strings. This means that they essentially shift any syntax errors that would normally be found at runtime back to compile time, and anyone that has studied the benefits of discovering bugs earlier in the development life-cycle knows that the earlier you find an error in the process, the cheaper it is to correct.

That’s all well and good, except that the performance price for doing this has sometimes been a factor of 10x. That is, queries that would take 500ms in Entity Framework have taken only 50ms in Dapper, a streamlined, cut down ORM (known as a Micro-ORM), and marginally less with a straight Sql Data Reader (perhaps around 48ms).

So many people, especially people that code for high performance sites, have moved away from Entity Framework and are now using Micro-ORMs, such as Dapper.

And as I’ve suggested above, the downside is that Micro-ORMs such as Dapper force us to return to using strings, which returns us to the position of potentially only discovering errors in SQL at runtime. To counteract this, developers must absolutely write a lot of tests to ensure this situation does not occur.

But for now, I want to see how to get the new Entity Framework to work, so I will set up the application to perform some work, then later on perhaps I will run a few tests comparing the new Entity Framework to Dapper.

So next, I need to install Entity Framework Core edition. And I want to configure it for Database First Migrations.

  1. Open up Package Manager Console, and run the following commands:
    Install-Package Microsoft.EntityFrameworkCore.SqlServer
    Install-Package Install-Package Microsoft.EntityFrameworkCore.Tools –Pre
    

    Note the Pre in the second command. That is because the Tools for the Entity Framework Core actually haven’t made it to RTM yet. They are still working on them. But in the meanwhile, we can still use the pre-release version. The Tools part is what gives us Migrations in the Package Manager Console.

  2. Some modifications are needed to the project.json file. Make the following additions to the project.json file, found in the root folder.
    {
      "dependencies": {
        "Microsoft.NETCore.App": {
          "version": "1.0.0",
          "type": "platform"
        },
        "Microsoft.AspNetCore.Diagnostics": "1.0.0",
        "Microsoft.AspNetCore.Server.IISIntegration": "1.0.0",
        "Microsoft.AspNetCore.Server.Kestrel": "1.0.0",
        "Microsoft.Extensions.Logging.Console": "1.0.0",
        "Microsoft.Extensions.Configuration.FileExtensions": "1.0.0",
        "Microsoft.Extensions.Configuration.Json": "1.0.0",
        "Microsoft.AspNetCore.StaticFiles": "1.0.0",
        "Microsoft.AspNetCore.Mvc": "1.0.0",
        "Microsoft.EntityFrameworkCore.SqlServer": "1.0.0",
        "Microsoft.EntityFrameworkCore.Design": {
          "type": "build",
          "version": "1.0.0-preview2-final"
        },
        "Microsoft.EntityFrameworkCore.Tools": "1.0.0-preview2-final"
      },
    
      "tools": {
        "Microsoft.EntityFrameworkCore.Tools": "1.0.0-preview2-final",
        "Microsoft.AspNetCore.Server.IISIntegration.Tools": "1.0.0-preview2-final"
      },
    
  3. Now we need a Database Context object. I created new Folder called DBML in the root of the project, and added a new class called HotelDbContext.
    my-first-asp-net-core-app-folder-structure-4
  4. Inside the HotelDbContext, I have inherited from the Entity Framework’s DbContext class, set up a constructor to pass in options such as the connection string, and made a reference to the Hotels DbSet. This is how EntityFramework knows that the Hotel class is what it wants to generate database objects for.
    namespace MyFirstAspNetCoreApp.DBML
    {
        public class HotelDbContext : DbContext
        {
            public HotelDbContext(DbContextOptions<HotelDbContext> options) : base(options)
            {
            }
            public DbSet<Hotel> Hotels { get; set; }
        }
    }
    
  5. The next task is to create the new Sql Hotel Data Service. We will switch the Hotel Data Service from the Dummy Hotel Data Service to the Sql Hotel Data Service.
    In the services folder, I have created a new IHotelDataService.cs file. I have taken the original IHotelDataService.cs interface and have now put that into the IHotelDataService.cs file, removing it from DummyHotelData.cs. Then I added a new class, which also inherits from IHotelDataService, as SqlHotelData. The Services folder now looks like this:
    my-first-asp-net-core-app-folder-structure-5
  6. Here is the new code for SqlHotelData:
    using System.Collections.Generic;
    using MyFirstAspNetCoreApp.Models;
    using MyFirstAspNetCoreApp.DBML;
    
    namespace MyFirstAspNetCoreApp.Services
    {
        public class SqlHotelData : IHotelDataService
        {
            private HotelDbContext context;
    
            public SqlHotelData(HotelDbContext context)
            {
                this.context = context;
            }
            public IEnumerable<Hotel> GetAll()
            {
                return this.context.Hotels;
            }
        }
    }
    

    Note that the SqlHotelData constructor takes a HotelDbContext object as an argument. This is passed in when the class is instantiated. I have then used that context object to obtain the list of Hotels in the GetAll() method.

  7. Back to configuration, and I have discovered that application settings are now meant to be stored in a file called appsettings.json. It says so in a comment the web.config file. So I have renamed my custom configuration file to appsettings.json.my-first-asp-net-core-app-folder-structure-6
  8. This requires a change in the Startup.cs file. Modify the Startup constructor to point to the correct settings json file:
    public Startup()
    {
        Configuration = new ConfigurationBuilder()
                       .SetBasePath(Directory.GetCurrentDirectory())
                       .AddJsonFile("appsettings.json")
                       .Build();
    }
    
  9. While we’re here, we may as well set the data context and redirect from the Dummy data source to the Sql data source. In the Configure Services method, comment out the old Dummy line and introduce the new Sql line:
    public void ConfigureServices(IServiceCollection services)
    {
       services.AddMvc();
       services.AddSingleton<IMyCustomConfiguration, MyCustomConfiguration>();
       services.AddSingleton(implementationFactory => Configuration);
    
       //services.AddScoped<IHotelDataService, DummyHotelData>();
       services.AddScoped<IHotelDataService, SqlHotelData>();
    }
    
  10. Now the reason I needed to fix up the appsettings file was that this is where I want to add in the database connection string. Go to the appsettings.json file and add a new connection string for the Hotel Database.
    {
      "my-custom-message": "The quick brown fox!",
      "ConnectionStrings": {
        "HotelDatabaseConnection" :  "Data Source=(localdb)\\mssqllocaldb;Initial Catalog=MyHotel"
      }
    }
    
  11. To wire this up and add the DbContext in, go back to the ConfigureServices method and add a services.AddDbContext line, as follows:
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddMvc();
        services.AddSingleton<IMyCustomConfiguration, MyCustomConfiguration>();
        services.AddSingleton(implementationFactory => Configuration);
    
        services.AddDbContext<HotelDbContext>(options => options.UseSqlServer(Configuration.GetConnectionString("HotelDatabaseConnection")));
        //services.AddScoped<IHotelDataService, DummyHotelData>();
        services.AddScoped<IHotelDataService, SqlHotelData>();
    }
    
  12. Now for the fun bit: Migrations. Because we’ve installed the Entity Framework Core tools and added the “Microsoft.EntityFrameworkCore.Design” dependency in the project.json file, we should now be able to run the migrations from the Package Manager Console window. Open up the Package Manager Console and type:
    Add-Migration MyFirstMigration
    

    If successful, it should show the line “To undo this action, use Remove-Migration.” If you look in you project, there should now be some generated migration code under a new folder called Migrations. I won’t go into it, but feel free to take a look at this.

  13. Finally, to get he migration to execute, go to the Package Manager Console and enter:
    Update-Database
    

    After a bit, it should respond with “Done.”

  14. Go to the View menu in Visual Studio 2015, and select “SQL Server Object Explorer”
    my-first-asp-net-core-app-sql-server-structure
  15. You should see the results above. But we’re not ready to execute it just yet – there is no data. Right click on the dbo.Hotels table and click View Data. We will insert the data there.
    my-first-asp-net-core-app-sql-server-data-entry
  16. Now run the application (F5), and you should see the new data appear in the browser:
    my-first-asp-net-core-app-updated-data
  17. And that’s it! Hopefully I haven’t missed anything. Post a comment if I have and I’ll try to be responsive and fix it pronto.

Notes from building a first ASP.Net Core App (part 8)

July 23, 2016
  1. To change it to a list of hotels, the first thing I want to do is set up a dummy data source for the hotels. That’s because I’m not actually getting the data from a database. I want to be able to switch the code over to a database at a later stage, and I don’t want the application to know when I do that. This is important for later, as it is this concept that allows us to independently unit test components.
  2. I have added a HotelDataService class to a Services folder at the top level of my Solution:
    my-first-asp-net-core-app-folder-structure-3x
  3. Inside the HotelDataService, I have the following code:
    namespace MyFirstAspNetCoreApp.Services
    {
        public interface IHotelDataService
        {
            IEnumerable<Hotel> GetAll();
        }
    
        public class DummyHotelData : IHotelDataService
        {
            IEnumerable<Hotel> hotels;
            public DummyHotelData()
            {
                hotels = new List<Hotel>
                {
                    new Hotel { Id = 1, DisplayName = "Sofitel" },
                    new Hotel { Id = 2, DisplayName = "Westin" },
                    new Hotel { Id = 3, DisplayName = "Novotel" }
                };
            }
    
            public IEnumerable<Hotel> GetAll()
            {
                return this.hotels;
            }
        }
    }
    
  4. By using an interface, we can separate the source of data from the delivery of that data.
  5. Next, we need to tell the application that this is a service to be injected into a page. And we need to tell it that the data that we want for now is the Dummy Hotel Data. That’s done back in the Startup class, in the ConfigureServices method, as follows:
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddMvc();
        services.AddSingleton<IMyCustomConfiguration, MyCustomConfiguration>();
        services.AddSingleton(implementationFactory => Configuration);
    
        services.AddScoped<IHotelDataService, DummyHotelData>();
    }
    

    Note the AddScoped method. This tells the application that each http request should get its own instance of that service, whatever the IHotelDataService supplies, which in this case is DummyHotelData.

  6. Back in the controller, the hotel data service can now by injected via the constructor. Remember, that’s the pattern with dependency injection now:
    namespace MyFirstAspNetCoreApp.Controllers
    {
        public class HomeController : Controller
        {
            private IHotelDataService hotelData;
    
            public HomeController(IHotelDataService hotelData)
            {
                this.hotelData = hotelData;
            }
            public IActionResult Index()
            {
                var model = hotelData.GetAll();
                return View(model);
            }
        }
    }
    

    See the addition of the HomeController constructor, with the hotel data service interface? The application understands that it needs to look up the list of services to obtain an instance from IHotelDataService. It is stored in a local variable that can then be used on the page.
    The model is then set to retrieve the data from the data source on line 13.

  7. Finally, I update the Index.cshtml page to strongly type the IEnumerable and also to display the entire list of hotels:
    @model IEnumerable<MyFirstAspNetCoreApp.Models.Hotel>
    <html>
    <head>
        <title>Home</title>
    </head>
    <body>
        <h1>Welcome!</h1>
        <ul>
            @foreach (var hotel in Model)
            {
            <li>
                @hotel.DisplayName
            </li>
            }
        </ul>
    </body>
    </html>