Scott Hanselman

AppVeyor - A good continuous integration system is a joy to behold

May 30, 2014 Comment on this post [22] Posted in Learning .NET
Sponsored By

All my open source projects building in AppVeyorEpisode 4 (that's from 2006, people, over 8 years ago!) of the Hanselminutes Podcast was on (CI) Continuous Integration. I was deep into CI at a large bank and having a blast. It's just such a joy to have a reliable and repeatable build. Even more so if setting up that build is easy. A good CI build that includes build, test, and deploy means you don't have to fear your code.

Back in the day we used Batch Files, dreams, and wishes to setup our CI systems. Later we moved to CruiseControl.NET. Today we've got lots of amazing options, some we can download and setup inside the company, and some hosted that require virtually no effort at all!

Like many of you, I've got a number of utilities and open source projects up on GitHub. Mine are at http://github.com/shanselman, of course.

However, some are older, some aren't often built, and honestly I couldn't tell you if they build anymore. Sometimes I'll even accept a Pull Request (PR) without really confirming that there isn't a missing semicolon or a syntax error. Ya, I said it. I haven't been nailed yet, but we all do it, and we know it's bad. A reliable CI system that kicks off a build on a commit is the only way to be sure.

I decided to revisit AppVeyor as an option for my CI system. I looked at it 18 months ago and it was time to check it out again.

Just to be clear, they don't know I'm writing this, I don't know AppVeyor, and I don't do paid reviews. This is all my opinion.

AppVeyor says they "automate building, testing and deployment of .NET applications helping your team to focus on delivering great apps."

Cool. I like automation, I like building, testing and deploying. I'm lazy, as are all good developers, so automated all the things!

Their pricing is impressive. It's free for unlimited public repositories, which means I can setup a CI build for all my little utilities and open source projects on GitHub. However, their Pro and Premium options are extremely competitive when compared against running my own VM and CI system in Azure for a month. 

Setting Up

I don't want to gush, but it's simple and gorgeous. I signed up with my GitHub creds (and also added BitBucket as I have some stuff there as well) and made a new project. They automatically sucked in my repositories, as well as the ones I have access to from other organizations. I selected a small one, my WiFi Manager for Windows 8, and clicked New Build.

It cloned my project and started building within a minute. I got an immediate failure, which surprised me.

Specify the Project

I stared at the error for a moment. Ah, my folder has more than one project or solution. Odd, there's just one project. Ah! But there's a foo.csproj AND a foo.sln.

Intuitively I go to Settings | Build, and enter the name of my csproj file. By the time I come back to the dashboard it's building again.

The build dashboard is at the same time impressive and comforting. It looks like a command prompt in HTML and it updates on its own, so you never feel like you're waiting or wondering what's happening.

Build Success

Amazing, look at that. It worked. I can add tests, and identify artifacts (results of the build) and act on them.

Here's my xUnit tests running automatically and their results showing up in the dashboard. Magic.

Tests too!

Here's AppVeyor uploading a build artifact.

Found an artifact

One EXE as Artifact

Here I've added an artifact and can download it and run it right from the browser. If your artifacts are NuGet packages, they'll even give you a private NuGet feed for those artifacts that you can use in other projects or automate yourself!

Finally you can automate deployment to whatever environment you like. Push to Blob Storage (like I do for myEcho), push to a NuGet server, or Web Deploy.

Deploy Anywhere

Impressively, AppVeyor restores NuGet packages as well. It even built a two year old ASP.NET MVC repository of mine on the first try.

So my open source project builds, now what? Now I add a status badge to my project's ReadMe.md to let everyone who visits my GitHub repository that this is a healthy project that is building successfully!

Status Badges

It literally took me longer to write this blog post than it did for me to setup Continuous Integration for FOUR open source projects in AppVeyor. Literally about 15 minutes from start to finish.

AppVeyor is really impressive, fun to use, and "just works." It's a great example of Software as a Service and the kinds of software I talked about in my recent post We are abstracting on the shoulders of giants.

With cloud apps like AppVeyor for build/test/deploy, services like like RayGun.io for error management, Trello for products backlogs, FreshDesk for support tickets, there's just so many great choices for a software companies large and small. It's a great time to be writing software.

Related Links


Sponsor: Big thanks to Mindscape for joining us and sponsoring the blog feed this week! I discovered Raygun.io and started using it for my side project and I LOVE it. Get notified of your software’s bugs as they happen! Raygun.io has error tracking solutions for every major programming language and platform - Start a free trial in under a minute!

About Scott

Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. He is a failed stand-up comic, a cornrower, and a book author.

facebook bluesky subscribe
About   Newsletter
Hosting By
Hosted on Linux using .NET in an Azure App Service

Xamarin.Forms - Write Once, Run Everywhere, AND Be Native?

May 28, 2014 Comment on this post [91] Posted in Mobile
Sponsored By
Xamarin lets you shared code across platforms

I worked in Java for a number of years at Nike, writing an order management application that would run on four platforms. We used to joke that we'd "write once, debug everywhere." Now, this was the early days of Java, but the thing was, every form and control was 'owner drawn.' That meant that a button looked the same everywhere because it wasn't a real button as far as the operating system was concerned. It was a picture of a button. We used to use Spy++ and different Windows inspector programs to explore our applications and they could never see a Java program's controls. This meant that the app pretty much worked everywhere, but the app always LOOKED like a Java App. They didn't integrated with the underlying platform.

With MVVM (Model, View, View-Model) patterns, and techniques like the Universal apps work on Windows Phone 8.1 and Windows 8.1, code sharing can get up into the high 90% for some kinds of apps. However, even for simple apps you've still got to create a custom native view for each platform. This is desirable in many cases, but for some app it's just boring, error prone, and tedious.

Xamarin announced Xamarin.Forms today which (in my words) effectively abstracts away native controls to a higher conceptual level. This, to my old eyes, is very similar to the way I wrote code in Java back in the day - it was all done in a fluent code-behind with layouts and flows. You create a control tree.

"Xamarin.Forms is a new library that enables you to build native UIs for iOS, Android and Windows Phone from a single, shared C# codebase. It provides more than 40 cross-platform controls and layouts which are mapped to native controls at runtime, which means that your user interfaces are fully native."

Xamarin uses Shared Projects in Visual StudioWhat's interesting about this, to me, is that these "control/concepts" (my term) are coded at a high level but rendered as their native counterparts. So a "tab" in my code is expressed in its most specific and native counterpart on the mobile device, rather than as a generic tab control as in my Java example. Let's see an example.

My buddy from Xamarin, James Montemagno, a fellow Chipotle lover, put together the ultimate cross-platform Hanselman application in a caffeinated late night hack to illustrate a few points for me. This little app is written in C# and runs natively on Windows Phone, Android, and iOS. It aggregates my blog and my tweets.

Here is the menu that switches between views:

WindowsPhone2Android2iPhone2

And the code that creates it. I've simplified a little for clarity, but the idea is all MVVM:

public HomeMasterView(HomeViewModel viewModel)
{
    this.Icon = "slideout.png";
    BindingContext = viewModel;

    var layout = new StackLayout { Spacing = 0 };

    var label = new ContentView {
        Padding = new Thickness(10, 36, 0, 5),
        BackgroundColor = Color.Transparent,
        Content = new Label {
            Text = "MENU",
            Font = Font.SystemFontOfSize (NamedSize.Medium)
        }
    };

    layout.Children.Add(label);
        
    var listView = new ListView ();

    var cell = new DataTemplate(typeof(ListImageCell));

    cell.SetBinding (TextCell.TextProperty, HomeViewModel.TitlePropertyName);
    cell.SetBinding (ImageCell.ImageSourceProperty, "Icon");

    listView.ItemTemplate = cell;

    listView.ItemsSource = viewModel.MenuItems;

//SNIP

listView.SelectedItem = viewModel.MenuItems[0]; layout.Children.Add(listView); Content = layout; }

Note a few things here. See the ListImageCell? He's subclassed ImageCell, which is a TextCell with an Image, and setup data binding for the text and the icon. There's recognition that every platform will have text and an icon, but the resources will be different on each. That's why the blog and Twitter icons are unique to each platform. The concepts are shared and the implementation is native and looks native.

That's the UI side, on the logic side all the code that loads the RSS feed and Tweets is shared across all three platforms. It can use async and await for non-blocking I/O and in the Twitter example, it uses LinqToTwitter as a PCL (Portable Class Library) which is cool. For RSS parsing, it's using Linq to XML.

private async Task ExecuteLoadItemsCommand()
{
    if (IsBusy)
        return;

    IsBusy = true;

    try{
        var httpClient = new HttpClient();
        var feed = "http://feeds.hanselman.com/ScottHanselman";
        var responseString = await httpClient.GetStringAsync(feed);

        FeedItems.Clear();
        var items = await ParseFeed(responseString);
        foreach (var item in items)
        {
            FeedItems.Add(item);
        }
    } catch (Exception ex) {
        var page = new ContentPage();
        var result = page.DisplayAlert ("Error", "Unable to load blog.", "OK", null);
    }

    IsBusy = false;
}

And ParseFeed:

private async Task<List<FeedItem>> ParseFeed(string rss)
{
    return await Task.Run(() =>
        {
            var xdoc = XDocument.Parse(rss);
            var id = 0;
            return (from item in xdoc.Descendants("item")
                select new FeedItem
                {
                    Title = (string)item.Element("title"),
                    Description = (string)item.Element("description"),
                    Link = (string)item.Element("link"),
                    PublishDate = (string)item.Element("pubDate"),
                    Category = (string)item.Element("category"),
                    Id = id++
                }).ToList();
        });
}

Again, all shared. When it comes time to output the data in a List on Windows Phone, Android, and iPhone, it looks awesome (read: native) on every platform without  having to actually do anything platform specific. The controls look native because they are native. Xamarin.Forms controls are a wrapper on native controls, they aren't new controls themselves.

WindowsPhone3Android3iPhone3

Here's BlogView. Things like ActivityIndicator are from Xamarin.Forms, and it expresses itself as a native control.

public BlogView ()
{
    BindingContext = new BlogFeedViewModel ();

    var refresh = new ToolbarItem {
        Command = ViewModel.LoadItemsCommand,
        Icon = "refresh.png",
        Name = "refresh",
        Priority = 0
    };

    ToolbarItems.Add (refresh);

    var stack = new StackLayout {
        Orientation = StackOrientation.Vertical,
        Padding = new Thickness(0, 8, 0, 8)
    };

    var activity = new ActivityIndicator {
        Color = Helpers.Color.DarkBlue.ToFormsColor(),
        IsEnabled = true
    };
    activity.SetBinding (ActivityIndicator.IsVisibleProperty, "IsBusy");
    activity.SetBinding (ActivityIndicator.IsRunningProperty, "IsBusy");

    stack.Children.Add (activity);

    var listView = new ListView ();

    listView.ItemsSource = ViewModel.FeedItems;

    var cell = new DataTemplate(typeof(ListTextCell));

    cell.SetBinding (TextCell.TextProperty, "Title");
    cell.SetBinding (TextCell.DetailProperty, "PublishDate");
    cell.SetValue(TextCell.StyleProperty, TextCellStyle.Vertical);

    listView.ItemTapped +=  (sender, args) => {
        if(listView.SelectedItem == null)
            return;
        this.Navigation.PushAsync(new BlogDetailsView(listView.SelectedItem as FeedItem));
        listView.SelectedItem = null;
    };

    listView.ItemTemplate = cell;

    stack.Children.Add (listView);

    Content = stack;
}

Xamarin Forms is a very clever and one might say, elegant, solution to the Write Once, Run Anywhere, AND Don't Suck problem. What's nice about this is that you can care about the underlying platform when you want to, and ignore it when you don't. A solution that HIDES the native platform isn't native then, is it? That'd be a lowest common denominator solution. This appears to be hiding the tedious and repetitive bits of cross-platform multi-device programming.

 

WindowsPhone1Android1iPhone1

There's more on Xamarin and Xamarin Forms at http://xamarin.com/forms and sample code here. Check out the code for the Hanselman App(s) at https://github.com/jamesmontemagno/Hanselman.Forms.

About Scott

Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. He is a failed stand-up comic, a cornrower, and a book author.

facebook bluesky subscribe
About   Newsletter
Hosting By
Hosted on Linux using .NET in an Azure App Service

We are abstracting on the shoulders of giants

May 28, 2014 Comment on this post [42] Posted in Musings
Sponsored By

middleMy new startup has data centers on three continents, utilizes global load-balancing, traverses networks with ease, has both an iPhone and Windows application, was written in a simple high level language, and enables an amazing scenario to help people get more done, faster.

But the real story - the real mindblower for me - was not the hours and hours of software that my partner and I wrote, it's the years and years of software that we didn't write.

We globally load balanced web sites and services across multiple servers in Europe, Asia, and the US. Windows Azure Traffic Manager handled that.

We sat our communication protocol on top of SignalR, an open source library using ASP.NET that hides the complexities of the real-time Web, handles NAT traversal for us, and basically removed the network for us as an issue. SignalR sits on stop of HTTP and Web Sockets, which sits on top of TCP/IP.

We used RayGun.io for our error management, and get complete stack dumps when a failure occurs in our application, this enables us to upgrade fast and often and give a good experience to our users

We used InnoSetup to install our application, it's truly one of the most amazing applications I've ever used. Give him money.

We used the ZXing QRCode Open source library for creation of QR codes. We didn't worry about the graphics details.

We used MahApps.Metro UI to make our Windows application look great. Added some controls, and it's lovely.

And it all comes together using C# and the Xamarin set of tools. The iPhone app, the Windows app, and the cloud service, are all C#.

I've been in the software industry for over 20 years now and I remember when writing C was considered a rather high-level language. I generally understand the full stack from assembler all the way up to managed code and beyond to the cloud. It's fantastic that today we think about managing VM clusters as much as we think about managing bytes.

Think about the giant shoulders that our application is standing on. Think about the shoulders that your application is standing on. Software abstraction has enabled us to do so much.

We can marvel at the abstraction layer that is Google. For many, that IS the internet. You type a question into a text box and push a button and the entire world opens up to you and a just a fraction of the planet truly appreciates the orchestration and history that makes it all happen.

Do I have a point here? Probably not. It just struck me today. Go listen to my chat with computer science legend Len Bass on this week's podcast to get a feeling for the history and power that we exploit every day.

There is value in taking a moment to think about the deep and broad stack that your application sits on. Go thank and support the projects, both open source and not, that your application uses. Revel in the layers of abstraction that others have created and appreciate the ones that you have created. They make all the LEGO pieces you're using just the correct size, and they make snapping them together a lot of fun.

It's a great time to be a programmer. This blog post was dictated with the myEcho application.

About Scott

Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. He is a failed stand-up comic, a cornrower, and a book author.

facebook bluesky subscribe
About   Newsletter
Hosting By
Hosted on Linux using .NET in an Azure App Service

Calculate your WEI (Windows Experience Index) under Windows 8.1

May 27, 2014 Comment on this post [48] Posted in Tools
Sponsored By

I used to be slightly obsessed with getting a high "WEI" in Windows. The Windows Experience Index was a number meant to give you an idea of how strong your PC was. The idea would be that you'd go get a game at the store and it would say "WEI 5 or greater" and you'd say, "oh, I have a 6, so this game will run great."

Under Windows 7 the maximum WEI was a 7.9, so I, of course, set off to build a machine that got a perfect 7.9 WEI.

In Windows 8 and 8.1, however, the friendly UI for showing your WEI is gone.

7.9 WEI

However, you can still get the RAW numbers in Windows 8.1, I'm told from a tipster who emailed me. (Thanks!)

First, run a cmd.exe prompt run "winsat prepop." If it fails to generate much output, try "winsat formal."

winsat prepop

Then, open a Powershell command prompt and run "Get-WmiObject -class Win32_WinSAT" and you'll see all your scores!

Get-WmiObject -class Win32_WinSAT

Looks like this machine is limited only by the SSD, but otherwise is an 8 class machine! I'm happy to be able to confirm my WEI again!

Does anyone know if Windows 8.1 maxes out at 8.9 or 9.9 WEI? Sound off in the comments!


Sponsor: Many thanks to Izenda for sponsoring the blog feed this week. Please do check out their Intuitive Ad Hoc Reporting with Stunning Visualizations - Embed real time dashboards into your ASP.NETapplications for easy, custom reports across all devices. Download a FREE TRIAL of Izenda Today!

About Scott

Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. He is a failed stand-up comic, a cornrower, and a book author.

facebook bluesky subscribe
About   Newsletter
Hosting By
Hosted on Linux using .NET in an Azure App Service

NuGet Package of the Week: ImageProcessor - lightweight image manipulation in C#

May 22, 2014 Comment on this post [38] Posted in NuGet | NuGetPOW
Sponsored By

I really enjoy image manipulation in code. Sure, resizing photos is fun in Photoshop, but there's something viscerally enjoyable when you change images with your own code.

I've talked about image resizing libraries like ImageResizer before, but there's certainly room for more than one. Today I want to showcase ImageProcessor, an open source "collection of lightweight libraries written in C# that allows you to manipulate images on-the-fly using .NET 4+." ImageProcessor is available on GitHub.

ImageProcessor

ImageProcessor methods include; Resize, Rotate, Rounded Corners, Flip, Crop, Watermark, Filter, Saturation, Brightness, Contrast, Quality, Format, Vignette, Gaussian Blur, Gaussian Sharpen, and Transparency.

ImageProcessor has a notable number of configuration options for web apps, and a supporting ImageProcessor.Web package as well. It's an impressive body of work.

I like this simple example of loading, resizing, and saving an image with their fluent API:

// Read a file and resize it.
byte[] photoBytes = File.ReadAllBytes(file);
int quality = 70;
ImageFormat format = ImageFormat.Jpeg;
Size size = new Size(150, 0)

using (MemoryStream inStream = new MemoryStream(photoBytes))
{
using (MemoryStream outStream = new MemoryStream())
{
using (ImageFactory imageFactory = new ImageFactory())
{
// Load, resize, set the format and quality and save an image.
imageFactory.Load(inStream)
.Resize(size)
.Format(format)
.Quality(quality)
.Save(outStream);
}

// Do something with the stream.
}
}

You can easily chain functions with the API, like tinting and constraning:

imageFactory.Load(inStream)
.Constrain(size)
.Tint(Color.FromArgb(255, 106, 166, 204))
.Format(format)
.Save(outStream);

When you add ImageProcessor.Web it adds caching that takes pressure off your web servers. You can easily add HttpHandlers to watermark an image, for example, and cache the result.

This is a library that has as a lot of potential. Since it's open source, I'm sure they'd appreciate help from the community! Personally, I think they could use more Unit Tests and more examples.

Head over to https://github.com/JimBobSquarePants/ImageProcessor and star this project! Get involved, file issues, and contribute! http://imageprocessor.org/

Related Links


Sponsor: Many thanks to Izenda for sponsoring the blog feed this week. Please do check out their Intuitive Ad Hoc Reporting with Stunning Visualizations - Embed real time dashboards into your ASP.NET applications for easy, custom reports across all devices. Download a FREE TRIAL of Izenda Today!

About Scott

Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. He is a failed stand-up comic, a cornrower, and a book author.

facebook bluesky subscribe
About   Newsletter
Hosting By
Hosted on Linux using .NET in an Azure App Service

Disclaimer: The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.