Scott Hanselman

Learning about the F# SAFE stack - Suave.io, Azure, Fable, Elmish

October 8, '17 Comments [16] Posted in DotNetCore | Open Source
Sponsored By

Last month I looked at a Functional Web with ASP.NET Core and F#'s Giraffe. Giraffe is F# middleware that takes ASP.NET Core's pipeline in a new direction with a functional perspective. However, Giraffe isn't the only F# web stack to choose from! There's Freya, WebSharper, and there's also a very interesting and quite complete story with The SAFE Stack.

The SAFE Stack

The SAFE Stack is an open source stack, like LAMP, or WAMP, or other acronym stacks, except this one is all open source .NET with a functional perspective. From the announcement blog:

  • Suave model for server-side web programming
  • Azure for cloud-based systems
  • Fable for Javascript-enabled applications.
  • Elmish for an easy-to-understand UI programming mode

To be clear, while this is a prescriptive stack, it's not a stack that forces you to do anything. You can swap bits out as you please.

Fable is particularly interesting as it's an F# to JavaScript transpiler. Try Fable online here http://fable.io/repl and turn F# into JavaScript LIVE! Their Sudoku sample is particularly impressive.

Here's two small - but interesting - examples where F# code ends up as JavaScript which ends up creating ReactJS components:

let words size message =
    R.span [ Style [ !!("fontSize", size |> sprintf "%dpx") ] ] [ R.str message ]

let buttonLink cssClass onClick elements = 
    R.a [ ClassName cssClass
          OnClick (fun _ -> onClick())
          OnTouchStart (fun _ -> onClick())
          Style [ !!("cursor", "pointer") ] ] elements

Then later in a Menu.fs that also turns into JavaScript eventually, you can see where they conditionally render the Button for logout, or links for for other Views for the Home Page or Wishlist. You can read lots more about Fable over at the Compositional IT blog.

let view (model:Model) dispatch =
    div [ centerStyle "row" ] [ 
          yield viewLink Home "Home"
          if model.User <> None then 
              yield viewLink Page.WishList "Wishlist"
          if model.User = None then 
              yield viewLink Login "Login" 
          else 
              yield buttonLink "logout" (fun _ -> dispatch Logout) [ str "Logout" ]
        ]

Elmish for F# takes the Model View Update (MVU) architecture and brings it to F# and the browser. There's a good breakdown of the value Elmish provides also at the Compositional IT blog.

Suave is its own cross platform Web Server. Here's Hello World in Suave.

open Suave

startWebServer defaultConfig (Successful.OK "Hello World!")

Suave has been around for while and gets better all the time. I blogged about it in 2015 and got it running on Azure. My blog post is not a best practice any more - it was a spike attempt by me - and fortunately they've moved on and improved things.

Here's Suave getting set up within the sample app. Check out how they route HTTP Verbs and URL paths.

    let serverConfig =
        { defaultConfig with
            logger = Targets.create LogLevel.Debug [|"ServerCode"; "Server" |]
            homeFolder = Some clientPath
            bindings = [ HttpBinding.create HTTP (IPAddress.Parse "0.0.0.0") port] }

    let app =
        choose [
            GET >=> choose [
                path "/" >=> Files.browseFileHome "index.html"
                pathRegex @"/(public|js|css|Images)/(.*)\.(css|png|gif|jpg|js|map)" >=> Files.browseHome

                path "/api/wishlist/" >=> WishList.getWishList loadFromDb ]

            POST >=> choose [
                path "/api/users/login" >=> Auth.login

                path "/api/wishlist/" >=> WishList.postWishList saveToDb
            ]

            NOT_FOUND "Page not found."

        ] >=> logWithLevelStructured Logging.Info logger logFormatStructured

    startWebServer serverConfig app

Very interesting stuff! There are so many options in .NET open source. I'll be doing podcasts on this stack soon.

Trying out the SAFE Stack

If you're using Visual Studio Community 2017, make sure you've got F# support included. I double-checked under Individual components. You can run the VS2017 installer multiple time and add and remove stuff without breaking things, so don't worry. If you are using other versions of VS, check here http://fsharp.org/use/windows/ to get the right download for your machine. If you're using Visual Studio Code, you'll want the Ionide F# plugin for Code.

Adding F# to Visual Studio Community 2017

Once I had node and yarn installed, it was easy to try out the sample app and get it running locally with "build run." It uses DotNetWatcher, so you can just keep it running in the background and work on your code and it'll recompile and restart as you go.

The SAFE stack running

The complete "SAFE" stack demo website is LIVE here http://fable-suave.azurewebsites.net (login test/test/) and all the source code for the app is here: https://github.com/SAFE-Stack/SAFE-BookStore.

UPDATE: One important point from F# Community Member Steffan Forkmann: "One thing I'd like to add is that SAFE is also an initiative to get multiple companies to give commercial support for this stack. This is IMHO very important for commercial use of an open source stack."


Sponsor: Do you know how many errors, crashes and performance issues your users are experiencing? Raygun installs in minutes. Discover problems you didn't even know about and replicate bugs with greater speed and accuracy. Learn more!

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 twitter subscribe
About   Newsletter
Sponsored By
Hosting By
Dedicated Windows Server Hosting by SherWeb

What would a cross-platform .NET UI Framework look like? Exploring Avalonia

September 21, '17 Comments [39] Posted in Open Source | WPF
Sponsored By

Many years ago before WPF was the "Windows Presentation Foundation" and introduced XAML as a UI markup language for .NET, Windows, and more, there was a project codenamed "Avalon." Avalon was WPF's codename. XAML is everywhere now, and the XAML Standard is a vocabulary specification.

Avalonia is an open source project that clearly takes its inspiration from Avalon and has an unapologetic love for XAML. Steven Kirk (GitHubber by day) and a team of nearly 50 contributors are asking what would a cross-platform .NET UI Framework look like. WPF without the W, if you will.

Avalonia (formerly known as Perspex) is a multi-platform .NET UI framework. It can run on Windows, Linux, Mac OS X, iOS and Android.

YOU can try out the latest build of Avalonia available for download here:https://ci.appveyor.com/project/AvaloniaUI/Avalonia/branch/master/artifacts and probably get the "ControlCatalog.Desktop" zip file at the bottom. It includes a complete running sample app that will let you explore the available controls.

Avalonia is cross-platform XAML ZOMG

It's important note that while Avalonia may smell like WPF, it's not WPF. It's not cross-platform WPF - it's Avalonia. Make sense? Avalonia does styles differently than WPF, and actually has a lot of subtle but significant syntax improvements.

Avalonia is a multi-platform windowing toolkit - somewhat like WPF - that is intended to be multi- platform. It supports XAML, lookless controls and a flexible styling system, and runs on Windows using Direct2D and other operating systems using Gtk & Cairo.

It's in an alpha state but there's an active community excited about it and there's even a Visual Studio Extension (VSIX) to help you get File | New Project support and create an app fast. You can check out the source for the sample apps here https://github.com/AvaloniaUI/Avalonia/tree/master/samples.

Just in the last few weeks you can see commits as they explore what a Linux-based .NET Core UI app would look like.

You can get an idea of what can be done with a framework like this by taking a look at how someone forked the MSBuildStructuredLog utility and ported it to Avalonia - making it cross-platform - in just hours. You can see a video of the port in action on Twitter. There is also a cross-platform REST client you can use to call your HTTP Web APIs at https://github.com/x2bool/restofus written with Avalonia.

The project is active but also short on documentation. I'm SURE that they'd love to hear from you on Twitter or in the issues on GitHub. Perhaps you could start contributing to open source and help Avalonia out!

What do you think?


Sponsor: Get the latest JetBrains Rider preview for .NET Core 2.0 support, Value Tracking and Call Tracking, MSTest runner, new code inspections and refactorings, and the Parallel Stacks view in debugger.

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 twitter subscribe
About   Newsletter
Sponsored By
Hosting By
Dedicated Windows Server Hosting by SherWeb

The ASP.NET Interns ship their project - A basic blog template for .NET Core

September 14, '17 Comments [12] Posted in DotNetCore | Open Source
Sponsored By

The internsThe Visual Studio Tools team had some great interns this summer. Juliet Daniel, Lucas Isaza, and Uma Lakshminarayan have been working all summer and one of their projects was to make something significant with ASP.NET Core and .NET Core. They decided to write a blog template. This is interesting as none of them had written C# or .NET before. Python, C, JavaScript, but not C#. This was a good exercise for them to not only learn C#/.NET but also give the team real feedback on the entire process. The ASP.NET Community Standup had the interns on the show to give us a walkthrough of their process and what they thought of VS.

They did their work over at https://github.com/VenusInterns/BlogTemplate so I'd encourage you to star their repository...and maybe get involved! This is a great starter application to explore ASP.NET and possibly do a pull request (make sure to give them a heads up in an issue before refactoring/changing everything ;) ) and contribute.

The interns used ASP.NET Core's new Razor Pages as well. Razor Pages sits on (is just) MVC so while it might initially look unfamiliar, remember that it's all still using the ASP.NET Core "MVC" pattern under the hood.

When you install the  .NET Core SDK you'll get a bunch of standard templates so you can:

  • dotnet new console
  • dotnet new mvc
  • dotnet new console --language F#
  • etc

There are lots of 3rd party and community templates and the beginnings of a website to search them. I expect this to be more formal and move into docs.microsoft.com in time.

The interns made "dotnet new blog" where blog is the short name of their template. They haven't yet released their template into NuGet for folks to easily install "dotnet new -I blogtemplate.whatever," For now you'll need to clone their repo as if you were developing a template yourself. It's actually a decent way for you to learn how to make templates.

Try this, using the .NET Core 2.0 SDK.

C:\> git clone https://github.com/VenusInterns/BlogTemplate.git
C:\> dotnet new -i C:\BlogTemplate -o C:\myblog
C:\> cd \myblog\BlogTemplate
C:\myblog\BlogTemplate> dotnet run
C:\myblog\BlogTemplate (master) > dotnet run
Using launch settings from C:\myblog\BlogTemplate\Properties\launchSettings.json...
Hosting environment: Development
Content root path: C:\myblog\BlogTemplate
Now listening on: http://localhost:59938
Application started. Press Ctrl+C to shut down.

And here's my nice local new blog. It's got admin, login, comments, the basics.

image

At this point you're running a blog. You'll see there is a Solution in there and a project, and because it's a template rather than a packaged project, you can open it up in Visual Studio Code and start making changes. This is an important point. This is an "instance" that you've created. At this point you're on your own. You can expand it, update it, because it's yours. Perhaps that's a good idea, perhaps not. Depends on your goals, but the intern's goal was to better understand the "dotnet new" functionality while making something real.

Here's some of the features the interns used, in their words.

  • Entity Framework provides an environment that makes it easy to work with relational data. In our scenario, that data comes in the form of blog posts and comments for each post.
  • The usage of LINQ (Language Integrated Query) enables the developer to store (query) items from the blog into a variety of targets like databases, xml documents (currently in use), and in-memory objects without having to redesign how things are queried, but rather where they are stored.
  • The blog is built on Razor Pages from ASP.NET Core. Because of this, developers with some knowledge of ASP.NET Core can learn about the pros and cons of building with Razor Pages as opposed to the previously established MVC schema.
  • The template includes a user authentication feature, done by implementing the new ASP.NET Identity Library for Razor Pages. This was a simple tool to add that consisted of installing the NuGet package and creating a new project with the package and then transferring the previous project files into this new project with Identity. Although a hassle, moving the files from one project to the other was quite simple because both projects were built with Razor Pages.
  • Customizing the theme is fast and flexible with the use of Bootstrap. Simply download a Bootstrap theme.min.css file and add it to the CSS folder in your project (wwwroot > css). You can find free or paid Bootstrap themes at websites such as bootswatch.com. You can delete our default theme file, journal-bootstrap.min.css, to remove the default theming. Run your project, and you'll see that the style of your blog has changed instantly.

I wouldn't say it's perfect or even production ready, but it's a great 0.1 start for the interns and an interesting codebase to read and improve!

Here's some ideas if you want a learning exercise!

  • Make the serializers swappable. Can you change XML to JSON or Markdown?
  • Make an RSS endpoint!
  • Add Captcha/reCaptcha
  • Add social buttons and sharing
  • Add Google AMP support (or don't because AMP sucks)
  • Add Twitter card support

You can also just play with their running instance here. Be nice. https://venusblog.azurewebsites.net/ (Username: webinterns@microsoft.com, Password: Password.1)


Sponsor: A third of teams don’t version control their database. Connect your database to your version control system with SQL Source Control and find out who made changes, what they did, and why. Learn more!

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 twitter subscribe
About   Newsletter
Sponsored By
Hosting By
Dedicated Windows Server Hosting by SherWeb

Experiments in Open Source: Exploring vcr-sharp for Http record and playback

September 10, '17 Comments [19] Posted in DotNetCore | Open Source
Sponsored By

I've always said that reading source code is as important as write it - especially as part of the learning process. You learn a ton about how other coders think and solve problems, plus you learn about lots of new libraries and methods you may not be familiar with.

Last week I noticed this tweet from Brendan Forster about an experiment he's working on. He is interesting in your feedback on his experiment and if you would use it.

He's created a new library for .NET called vcr-sharp that is inspired by the vcr Ruby gem and the scotch .NET library.

Again, he's made it clear he's just experimenting but I think this has some interesting potential.

Vcr-sharp lets you record and playback HTTP requests! In this example, WithCassette is an extension method on HttpClientFactory. That extension method sets up a DelgatingHandler to a ReplayingHandler. That ReplayingHandler "loads the cassette" and returns it as a cached response.

using (var httpClient = HttpClientFactory.WithCassette("my-test-scenario"))
{
var request = new HttpRequestMessage(HttpMethod.Get, "http://www.iana.org/domains/reserved");
var response = await httpClient.SendAsync(request);
var body = await response.Content.ReadAsStringAsync();
body.ShouldContain("Example domains");
}

Also worth noting is that within the VCR-Sharp library Brendan uses an assertion library for .NET called "Shouldly." Shouldly has some interesting extension methods that let you express how you Assert within your Tests.

They say - this is the old Assert way:

Assert.That(contestant.Points, Is.EqualTo(1337));

For your troubles, you get this message, when it fails:

Expected 1337 but was 0

They say - this is how it Should be:

contestant.Points.ShouldBe(1337);

Which is just syntax, so far, but check out the message when it fails:

contestant.Points should be 1337 but was 0

Another example:

Assert.That(map.IndexOfValue("boo"), Is.EqualTo(2));    // -> Expected 2 but was 1
map.IndexOfValue("boo").ShouldBe(2);                    // -> map.IndexOfValue("boo") should be 2 but was 1

It makes tests very easy to read. A nice bit of syntactic sugar:

[Fact]
public async Task AppendsNewRequestToCache()
{
Environment.SetEnvironmentVariable("VCR_MODE", "Cache");
var session = "append-second-request";

using (var httpClient = HttpClientFactory.WithCassette(session))
{
var request = new HttpRequestMessage(HttpMethod.Get, "https://www.iana.org/performance/ietf-statistics");
var response = await httpClient.SendAsync(request);
}

var cassette = await ReadCassetteFile(session);
cassette.http_interactions.Length.ShouldBe(2);
}

It also uses BenchmarkDotNet, which you may be familiar with. It allows you to mark methods as [Benchmark] methods and you'll get smart warming up, running, teardowns and statistics like this;

[Benchmark]
public async Task ReadFromCache()
{

using (var httpClient = HttpClientFactory.WithCassette("example-test"))
{
var request = new HttpRequestMessage(HttpMethod.Get, "http://www.iana.org/domains/reserved");
var response = await httpClient.SendAsync(request);
}
} Output:
        Method |     Mean |    Error |   StdDev |
-------------- |---------:|---------:|---------:|
ReadFromCache | 684.1 us | 3.154 us | 2.796 us |

I'd encourage you to check vcr-sharp out over at https://github.com/shiftkey/vcr-sharp, read the source code, and think about how you'd use it. I am sure Brendan would appreciate your thoughts and feedback in the GitHub Issues! Also check out how he uses Tests, Shouldly, and BenchmarkDotNet in his project and consider how you'd use them in yours!


Sponsor: Raygun provides real time .NET error monitoring and supports all other major programming languages and frameworks too! Forget logs and support tickets. Reproduce software bugs in minutes with Raygun's error tracking software!

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 twitter subscribe
About   Newsletter
Sponsored By
Hosting By
Dedicated Windows Server Hosting by SherWeb

T4MVC and R4MVC - Roslyn code generators for ASP.NET Core tag helpers

September 7, '17 Comments [21] Posted in ASP.NET MVC | Open Source
Sponsored By

I've always loved the T4 text generator within Visual Studio. If you are looking for T4 within Visual Studio 2017 you need to install the "Visual Studio extension development" option within the installer to access it. However, T4 development seems stalled/done and if you want to utilize some of it.

There's a nice open source project called T4MVC that you can use with Visual Studio 2015 and ASP.NET MVC to create strongly typed helpers that eliminate the use of literal strings in many places. That means instead of:

@Html.ActionLink("Dinner Details", "Details", "Dinners", new { id = Model.DinnerID }, null)

T4MVC lets you write

@Html.ActionLink("Dinner Details", MVC.Dinners.Details(Model.DinnerID))

Fast forward to 2017 and that team is working on a new project called R4MVC...it's a code generator that's based on Roslyn, the .NET Compiler Platform (hence the R).

It also lets you update your @Html.ActionLinks to be strongly typed, but more importantly it lets you extend that to strongly typed taghelpers, so instead of:

<a asp-action="Details" asp-controller="Dinners" asp-route-id="@Model.DinnerID">Dinner Details</a>

you can write

<a mvc-action="MVC.Dinners.Details(Model.DinnerID)">Dinner Details</a>

It's generating the URL for that <a> tag using the method and parameter.

Using an ASP.NET Core 1.1 app (2.0 is coming soon they say) I'll add the NuGet packages R4Mvc.Tools and R4Mvc, making sure to "include prerelease."

Adding R4Mvc.Tools in NuGet

I'll run "Generate-R4MVC" in the Package Manager Console.

Generate-R4MVC

There is a new R4Mvc.generated.cs file that gets created, and inside it is a whole bunch of classes based on the files on disk. For example I can type @Links.css, or @Links.lib and start getting intellisense for all my files on disk like JavaScript or CSS.

Links.css

When returning a view, rather than return View("About") I can do return View(Views.About):

return View(Views.About)

The R4MVC project also has Tag Helpers so their mvc-action attribute gives you strong typing like this:

<a mvc-action="MVC.Home.Index()">

This R4MVC project is just getting started, but I'm sure they'd appreciate your support! Head over to https://github.com/T4MVC/R4MVC/issues and learn about what they are planning and perhaps help out!

What do you think? Do you think there's value in smarter or strongly-typed URL generation with ASP.NET?


Sponsor: Raygun provides real time .NET error monitoring and supports all other major programming languages and frameworks too! Forget logs and support tickets. Reproduce software bugs in minutes with Raygun's error tracking software!

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 twitter subscribe
About   Newsletter
Sponsored By
Hosting By
Dedicated Windows Server Hosting by SherWeb
Previous Page Page 2 of 46 in the Open Source category Next Page

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