DNX: working Console Application

This is archive material: the syntax below no longer works. By Microsoft’s own admission I believe, while fun, this was barely alpha. See .Net Core 2 blog here.

Summary: I have at least proven that I can run a Console App from the command line, using dnu, dnx, dnvm, yada.This is the output from an hour’s effort, that it is, a console app called using dnx.exe:

VSDNX17

The snippets below record my steps a) to see if by building a console app in VS2015 using a template I could infer exactly how it is done manually, b) failing to understand why it could not resolve the System.* dependencies, c) ignoring guidance in MSDN blogs about Nuget package manager in VS sorting it out, and instead letting dnvm restore do its job, d) F5 and ctrl-F5 to get a clue about how it is executed (i.e. the path to the required dnx.exe), e) executing dnx.exe from the command line, passing in the location of the project.json file, which holds all the necessary info about how and what to execute, f) an implicit confirmation that console applications are no longer about building and running an .exe. (And I get that aspVNext/Roslyn etc is not per se about console apps – I was just looking for a way to do the simplest thing, with the smallest number of dependencies. This at least does now open up the door to knowing (I think!) how I can execute this on a low power Windows machine (or Linux – I have no access to OSX) without Visual Studio present. I could of course just have grabbed an old style csc.exe… but this is about doing Roslyn and related, not revisiting old ground. So the noisy snippets:

VSDNX01

VSDNX02

VSDNX03

VSDNX04

VSDNX05

VSDNX07

VSDNX08

VSDNX09

VSDNX10

VSDNX11 VSDNX12

VSDNX13

VSDNX14

VSDNX15

VSDNX16

VSDNX17

Advertisements

DNX

Just a bunch of links and shots right now:

aspnet 1,

I already have VS installed on my machine, hence presumably why it finds [dnvm]:

dnx01

dnx02

dnvm upgrade:

dnx03

Build script location:

dnx04

I cloned the repo to my desktop:

dnx05

Then ran a build.cmd… just to see:

dnx06

 

dnx07

The remainder is screenshots based on this post. Didn’t get to the end as although I selected a console app, it has generated a dll. My stamina has now gone.

dnx01 dnx02 dnx03 dnx04 dnx05 dnx06 dnx07 gruntdnx01 gruntdnx02 gruntdnx03 gruntdnx04 gruntdnx05 gruntdnx06 gruntdnx07 gruntdnx08 gruntdnx09 gruntdnx10 VSJson01 VSJson02 VSJson03 VSJson04 VSJson06 VSJson07 VSJson08

 

 

Visual Studio Code: Roslyn and OmniSharp with the C# compiler on Windows

(A month is a long time in .Net, right now. Looking back at this, it clearly predates my getting to grips with project.json. I’m leaving it here as I find it instructive to leave my naive attempts in place.)

  • Visual Studio 2015: I abbreviate this to VS
  • Visual Studio Code: I abbreviate this to VSC

Summary

This is aimed at C# programmers on Windows, who are used to doing all their editing and dev compilation in VS. In VSC, you can edit existing .cs files which are already part of a parent .sln file. Doing this, you will get Intellisense and a whole bunch of richness. However if you create new .cs files, then to get Intellisense etc, you must first go to VS and add that new file to a .csproj and .sln (or write some command line transformer to add the .cs files… or a Task in VS). With a little one-off effort, you can compile inside VSC. 

If you are using VSC on Windows, and you are writing C#, and you want OmniSharp and Intellisense to work… then you must have a VS Solution in place. I emphasise that, because I first did not entirely digest this point here:

OmniSharp01

As a C# programmer, just heed the stuff in the orange borders. As ever, some screenshots illustrate the point. Firstly, this is what happens if you naively open a .cs file in VSC that does not ultimately have a parent .sln file:

OmniSharp02

After typing [System.] above, I pressed [ctrl-space], which returns [No suggestion]. That is because App1.cs is standalone, and has no VS Solution context. It is however perfectly valid C#  (once I fix the syntax):

OmniSharp03

But if in VS I now create a simple console app, and therefore get a .sln file, with the simple .cs existing in the context of that Solution, we see this in VS:

OmniSharp04

I then locate the solution in VSC:

OmniSharp05

, and open the program file. We then get all the Intellisense and OmniSharp checks:

OmniSharp06

Doing a bit more editing shows that you get:

  • IntelliSense (as said)
  • Redundant Usings warnings
  • A summary of warnings
  • snippet/auto completion (I haven’t yet worked out where it gets these), but e.g. CW does the right thing
  • Code formatting (I haven’t worked out how you set this to your standards)
  • Code Lens

OmniSharp07

So all in all, I THINK it was worth the pain… my use-case is that for the trade-off of creating at least a skeleton project in VS, I can edit on a non-full-power box. But right now, I see this being more for a scratchpad or POC application, rather than an enterprise-size application. That might not be true for an AngularJS app – I suspect it is not true given all the passion on Twitter etc for this from JavaScript people. But it does have a very small footprint. I have a Linx 2GB/32GB Windows 10 tablet, and whereas it struggled to cope with a full VS environment, I’m sure this will be easy for it. That is the use-case I guess (note I am specifically talking about C# usage, not JavaScript etc)

And note that you don’t somehow download OmniSharp, or direct VSC to find it as an extension. No, it is evidently part of VSC, on Windows anyway.

Roslyn: First Steps

Roslyn, AKA the .Net Compiler Platform, is used in Visual Studio 2015 for the C# and Visual Basic compilers. MS Blog. My motivation is that I want a simple, small C# compiler footprint that I can use with Visual Studio Code.

Now Visual Studio is anything but lightweight (they REALLY got this naming wrong between VS and VS Code)… but if you go to Roslyn on GitHub, download Nuget.exe as Raw, go to Powershell I guess as Administrator, and run this:

.\nuget.exe install Microsoft.Net.Compilers

then you get the csc.exe and its dependencies.

Screenshots to cover all that:

Nuget01

Nuget02

Nuget03

Nuget04

Nuget06

Nuget05

Nuget07

NugetRoslyn08

NugetRoslyn09

NugetRoslyn10

OmniSharp01

OmniSharp02 OmniSharp03

OmniSharp04

OmniSharp05

OmniSharp06 OmniSharp07

Compilation using csc.exe

We then come to actually compiling something trivial. msdn guidance here.

This is a linked page from there to the simplest possible console app. Just SO disappointing in a page about VS2015, they’re using a Windows Batch script to wrap it and not PowerShell. Anyhoo… if you have this content:

(tidy up another time)

Link to the Roslyn wiki on GitHub: https://github.com/dotnet/roslyn/wiki/FAQ

Cycling: those vulnerable road bike inner tubes

On Sunday, we had the pleasure of Emma joining us for an early bike ride (that’s not significant for the post, but I choose to throw it in 🙂 ). Emma and I had the hybrids, which already have the excellent Slime inner tubes, and which in the space of a lot of cycling over 3 years, have never let us down. In addition, Jan has a road bike, and I’ve recently bought one. Jan used the road bike for this ride. Once again, riding on a path, the road bike got a puncture. On average therefore, I would say we get a puncture one in every five 25 mile rides.

So yesterday we bought a pair of slime tyres for the road bikes. Although we like to go at a reasonable pace, we are not bothered about squeezing that last drop of performance out of our bikes. Thus, any weight or speed penalty the Slime introduces is justified by less time fitting a new tube or a sticky by the side of the road.

I’ll update this post if the road bike Slime does get a puncture which doesn’t repair itself.

For reference, below is a picture of the tube I used – 700X 19/25C. In fact the previous tyre was a 23C, but the tube fitted fine. If anything, it was easier to put on than the Slime on the hybrid. If you have not used these before, be aware that inflating the tyre can be a bit messy, at least when you are pressing the valve down to ensure it is free.

We got the tyres from Wilkinsons‘, which are great value at £6 each, right now. Retail is normally £10 or so I think.

WP_20151027_14_24_09_Pro WP_20151027_14_24_01_Pro

WP_20151027_12_17_17_Pro

C#: using Linq for a deep copy

Dirty little console app, but it illustrates the point well enough, I think:

LinqDeepCopy01

LinqDeepCopy02

LinqDeepCopy03 LinqDeepCopy04

Snippet

using System.Collections.Generic;
using System.Linq;
 
namespace ConsoleApplication3 {
    class Program {
 
        private List<Shoe> _shoesByRef;
        private List<Shoe> _shoesByValue;
 
        public List<Shoe> MyShoes {
            get { return _shoesByRef; }
            set { _shoesByRef = value; }
        }
 
        static void Main(string[] args) {
            var shoes = new List<Shoe> {
                new Shoe { ShoeName = "Clarks", ShoeSize = 12 },
                new Shoe { ShoeName = "Tuf", ShoeSize = 4 }
            };
 
            var p = new Program(shoes);
 
        }
 
        public Program(List<Shoe> shoeSet) {
            // _shoesByRef is a reference to the passed-in shoeSet...
            _shoesByRef = shoeSet;
            // _shoesByValue on the other hand is a deep-copy of _shoesByRef...
            _shoesByValue = new List<Shoe>(_shoesByRef.Select(s => 
                                new Shoe() { ShoeName = s.ShoeName, ShoeSize = s.ShoeSize }));
            // That means we can now set _shoesByRef to null...
            _shoesByRef = null;
            // ... and because _shoesByValue is independent of _shoesByRef, then it still exists:
            foreach (var shoe in _shoesByValue) {
                System.Console.WriteLine("{0};{1}", shoe.ShoeName, shoe.ShoeSize);
            }
        }
    }
 
    internal class Shoe {
 
        private int _shoeSize;
 
        public int ShoeSize {
            get { return _shoeSize; }
            set { _shoeSize = value; }
        }
 
        private string _shoeName;
 
        public string ShoeName {
            get { return _shoeName; }
            set { _shoeName = value; }
        }
    }
}

This mod is to check that the copy went well. Annotation in the code hopefully enough…

LinqDeepCopy05

LinqDeepCopy06

Snippet

using System.Collections.Generic;
using System.Linq;
 
namespace ConsoleApplication3 {
    class Program {
 
        private List<Shoe> _shoesByRef;
        private List<Shoe> _shoesByValue;
 
        public List<Shoe> MyShoes {
            get { return _shoesByRef; }
            set { _shoesByRef = value; }
        }
 
        static void Main(string[] args) {
            var shoes = new List<Shoe> {
                new Shoe { ShoeName = "Clarks", ShoeSize = 12 },
                new Shoe { ShoeName = "Tuf", ShoeSize = 4 }
            };
 
            var p = new Program(shoes);
 
        }
 
        public Program(List<Shoe> shoeSet) {
            // _shoesByRef is a reference to the passed-in shoeSet...
            _shoesByRef = shoeSet;
            // _shoesByValue on the other hand is a deep-copy of _shoesByRef...
            _shoesByValue = new List<Shoe>(_shoesByRef.Select(s => 
                                new Shoe() { ShoeName = s.ShoeName, ShoeSize = s.ShoeSize }));
            // That means we can now set _shoesByRef to null...
            _shoesByRef = null;
            //shoeSet = null;
            // ... and because _shoesByValue is independent of _shoesByRef, then it still exists:
            foreach (var shoe in _shoesByValue) {
                System.Console.WriteLine("{0};{1}", shoe.ShoeName, shoe.ShoeSize);
            }
 
            // Check that the original set has been faithfully copied (expect "True" if it has)...
            var allFound = shoeSet.All(e => _shoesByValue.Any(es => (es.ShoeName == e.ShoeName && es.ShoeSize == e.ShoeSize)));
            System.Console.WriteLine(allFound);
 
            // now set 1 of the byvalue properties to a different value so that the source will not find a match in 1 case:
            // (Now expect false...)
            _shoesByValue[0].ShoeSize = 42;
            foreach (var shoe in _shoesByValue) {
                System.Console.WriteLine("_shoesByValue: {0};{1}", shoe.ShoeName, shoe.ShoeSize);
            }
            foreach (var shoe in shoeSet) {
                System.Console.WriteLine("shoeSet: {0};{1}", shoe.ShoeName, shoe.ShoeSize);
            }
 
            allFound = shoeSet.All(e => _shoesByValue.Any(es => (es.ShoeName == e.ShoeName && es.ShoeSize == e.ShoeSize)));
            System.Console.WriteLine(allFound);
 
        }
    }
 
    internal class Shoe {
 
        private int _shoeSize;
 
        public int ShoeSize {
            get { return _shoeSize; }
            set { _shoeSize = value; }
        }
 
        private string _shoeName;
 
        public string ShoeName {
            get { return _shoeName; }
            set { _shoeName = value; }
        }
    }
}