Rockford Lhotka's Blog

Home | Lhotka.net | CSLA .NET

 Friday, 12 February 2016

This Neowin article asks people whether they use many actual Windows 10 (WinRT or UWP) apps. I knew I used quite a few, but decided to make a list of the ones I use on a regular basis (all at least once a week, but many of them several times a day).

Of course I have a lot more installed, but I don’t actually use them often, or at all. Someday I should do a purge of old stuff I installed to try and then never used again…

Here’s my list of apps that I use on a regular/consistent basis (not in any particular order):

Cortana - my indispensable digital assistant (Siri is like her dullard older sister)
Clipboard - share anything to the clipboard - indispensable utility app
PowerBI – watch my VSTS and GitHub repos, plus Magenic business dashboards
Email and Calendar (yes, they are finally quite good apps)
OneNote (the touch version is better than the Win32 version on a Surface - by far)
MyRadar - useful on every device everywhere!!
Tweetium - excellent twitter client - I love it!
News - the msn/bing news app - I use it on my iPhone too - very nice
Weather - I wish wunderground had an app, but the msn/bing one _is_ very nice
NextGen Reader - I wish _this_ was on the iPhone - what a great way to consume the web
Groove Music - as a subscriber, this is a no-brainer
Movies and TV - this is how I get my Doctor Who (legally)
iHeartRadio - better ad-hoc radio than Groove
Vevo - when I want music videos, not just music
MyTrips - TripIt client that's better than the 1st party offering
Wunderlist - how I organize my life
Words with Friends - a primary source of entertainment
HealthVault - with my health issues, this is critical
Readit - I'm not a reddit fan, but sometimes you gotta go to reddit
Reading List - Msft seems to want to kill this off, but it is a really nice app!
DropBox - access my lesser used files (mostly I use OneDrive)
Box - access my even lesser used files
Fitbit - nicer/easier than via the web
Gitty - adequate gitter client for chatting about OSS GitHub-hosted projects
Hulu Plus - obvious
Netflix - obvious
LastPass - Win8-era app, but still nicer than using the browser
NFL on Windows - every NFL fan should have this app - seriously!
NPR One - best way to listen to NPR (and in my case MPR)
Uber - order my ride at the end of a work day when travelling
Photos – I have a _lot_ of photos, all in OneDrive

Friday, 12 February 2016 11:28:12 (Central Standard Time, UTC-06:00)  #    Disclaimer
 Friday, 06 November 2015

.NET Core is somewhat confusing to a lot of people. In short, .NET Core is an open source reimplementation of .NET that Microsoft has been, and continues to, work on completing. The Universal Windows Platform (UWP) runs on .NET Core, as does the upcoming ASP.NET 5 technology. What is a little confusing is that ASP.NET 5 also runs on full .NET 4.6 – it can run on either NET implementation.

One of the biggest things to understand about .NET Core is that Microsoft is working hard to keep it very modular. Unlike full .NET, where a lot of things are in a few assemblies, in .NET Core there are a lot of assemblies with a few things in each. And those assemblies are generally available via NuGet, not included by default as part of the “.NET Core install”. The advantage to this is that your app can be more lean, because generally we’ll bring in only the framework assemblies we need, where in full .NET a lot of unneeded stuff tends to just come along for the ride.

Getting to UWP

Some time ago I added Windows 10 UWP support to CSLA .NET, which means that I already did some work to get CSLA running on .NET Core. However, the UWP project template in Visual Studio is somewhat forgiving, in that it brings in several .NET framework components that aren’t automatically brought in if you create a bare-bones .NET Core class project. This makes sense, because there are a set of assemblies necessary to support UWP and I think we’d all expect those to be automatically available to any UWP project.

The CSLA UWP project targets Windows 10.

snip_20151105231251

Or in project.json terms:

{
  "dependencies": {
    "Microsoft.NETCore.UniversalWindowsPlatform": "5.0.0"
  },
  "frameworks": {
    "uap10.0": {}
  },
  "runtimes": {
    "win10-arm": {},
    "win10-arm-aot": {},
    "win10-x86": {},
    "win10-x86-aot": {},
    "win10-x64": {},
    "win10-x64-aot": {}
  }
}

Back in the Windows 8 timeframe we did a bunch of work to support the Wiindows Runtime (WinRT). WinRT is quite a lot like Silverlight, in that apps run in a sandbox and have access to a subset of .NET. So getting CSLA running for WinRT wasn’t too hard because we already supported Silverlight before Windows 8 came along. However, WinRT changed reflection in some pretty radical ways, and we had to do quite a lot of work to replicate the old-style reflection API and behaviors in the WinRT world.

UWP now runs on .NET Core, which is a reengineered subset of full .NET, and UWP apps use the WinRT API from a UI perspective. So really UWP apps are very comparable to WinRT apps. That said, Microsoft did take this opportunity to yet again tweak reflection, so I used the WINDOWS_UWP compiler symbol to provide UWP-friendly implementations of the reflection fixes we’d created for WinRT. Whew!

snip_20151105232029

(to be honest, some of the code in the TypeExtensions class are basically placeholders that need more work to be complete; for example: TypeExtensions.GetConstructor is not implemented properly)

The final thing to understand about the existing UWP support is that .NET Core code can be compiled to native – in fact it will be compiled to native by the Windows Store to provide the end user with the best performance. Compiling .NET code to native is a fairly complex process and one part of that process is that the end result only contains the code that is known to be invoked – all other code is literally left out of the end result. If you don’t use reflection this is not a problem, but if you do use reflection (and CSLA does) then it is important to tell the native compilation process not to “optimize” away code you might actually be calling.

To do this you edit a file in your UWP application’s Properties folder called myapp.rd.xml. In this file you indicate the assemblies that shouldn’t be optimized. For example:

<Directives xmlns="http://schemas.microsoft.com/netfx/2013/01/metadata">
  <Library Name="Csla.Uwp">
    <Assembly Name="Csla" Activate="Required All" Browse="Required All" Serialize="Required All" Dynamic="Required All" />
  </Library>
</Directives>

This says that Csla.dll shouldn’t be optimized away – which is probably fine because it isn’t very big to start with. And you absolutely must ensure that your business assemblies aren’t optimized because CSLA reflects against your business assemblies to do its work. Again, probably not a big deal because your business assembly should be containing business code and not UI assets or other large artifacts – in other words it shouldn’t be terribly large either.

This is done in your UWP app project – the one that gets built and deployed to the user – and the one that typically references your business assemblies and CSLA.

Getting to .NET Core

Given everything I just discussed regarding UWP, it seems like getting a “pure” .NET Core assembly for CSLA wouldn’t be too hard. But there were some unexpected hurdles I’ll discuss.

The first step to creating a class library project for .NET Core is to create a portable class library (PCL) project that targets .NET 4.6 and ASP.NET Core 5.0.

snip_20151105233800

This creates a project with the correct functional cross-section to target .NET Core.

Some time ago I refactored the CSLA codebase so all the actual code files are in a shared project named Csla.Shared. We then have a concrete project for each target platform we support (Xamarin Android and iOS, iOS Classic, .NET 4, 4.5, 4.6, WinRT, UWP, etc.).

snip_20151105234241

This new PCL project is named Csla.NetCore5.0 and it just references that pre-existing shared project to get the same code as every other version of CSLA.

snip_20151105234409

As I mentioned earlier, this bare-bones class library project doesn’t bring in any more of .NET than absolutely necessary. As a result I had to add some NuGet packages required by CSLA.

snip_20151105234659

Or via project.json:

{
  "supports": {
    "net46.app": {},
    "dnxcore50.app": {}
  },
  "dependencies": {
    "Microsoft.NETCore": "5.0.0",
    "Microsoft.NETCore.Portable.Compatibility": "1.0.0",
    "System.Runtime.Serialization.Primitives": "4.0.10",
    "System.Runtime.Serialization.Xml": "4.0.10",
    "System.Threading.ThreadPool" : "4.0.10-beta-23409"
  },
  "frameworks": {
    "dotnet": {
      "imports": "portable-net452"
    }
  }
}

This brings in the BCL functionality required by CSLA.

The one exception is that I didn’t bring in WCF. Instead what I’ve done at the moment is to use a NETCORE compiler directive symbol to exclude the data portal WCF channel from building as part of CSLA for .NET Core. The reason for this is that I had a conversation with one of the Microsoft engineers responsible for this, and it turns out that referencing WCF has a cascade effect where a very large percentage of .NET gets brought into scope (to support WCF).

If your app doesn’t use the WCF data portal channel you shouldn’t have to include all that extraneous code/assemblies in your app. So rather than including the WCF data portal support into core CSLA my plan is to follow the lead of .NET Core itself and break the WCF data portal channel into its own separate assembly (Create .NET Core WCF data portal channel assembly).

There’s one other issue I had to deal with, and that is that in my UWP implementation I used some WinRT APIs – and those aren’t available in “pure” .NET Core. The most notable of these is code in CSLA that captures and restores the current culture and UI culture values on the current thread. Some of this is extremely old code that used to pull the information off the current thread, and then along came WinRT that required a different approach. It turns out that in .NET 4 Microsoft introduced a new API to consolidate the old and new styles of interacting with the culture values. For example, you can now do this:

request.ClientCulture = System.Globalization.CultureInfo.CurrentCulture.Name;
request.ClientUICulture = System.Globalization.CultureInfo.CurrentUICulture.Name;

The code here works on all platforms, no need to use the current thread in .NET and some WinRT API elsewhere. Very nice!

The one catch is that setting the culture isn’t universally supported in a single model because older versions of .NET (like 4) still require the use of the Thread object. So setting the culture requires a compiler directive.

#if NETFX_CORE
        _clientCulture = System.Globalization.CultureInfo.CurrentUICulture.Name;
        _clientUICulture = System.Globalization.CultureInfo.CurrentUICulture.Name;
#else
        _clientCulture = System.Threading.Thread.CurrentThread.CurrentCulture.Name;
        _clientUICulture = System.Threading.Thread.CurrentThread.CurrentUICulture.Name;
#endif

And that’s it – pretty easy really – thanks to having added Silverlight support years ago, followed by WinRT support, then UWP support. All the groundwork was laid for pure .NET Core support.

(and it helped that I was doing this work in Redmond so I had direct access to Microsoft engineers that are creating .NET Core Smile )

Just at the moment this work is available in a branch of my fork: https://github.com/rockfordlhotka/csla/tree/337-NetCoreSupport

Once I’ve done some more testing I’ll merge this into the actual CSLA master branch at: https://github.com/MarimerLLC/csla/tree/master

Friday, 06 November 2015 02:11:37 (Central Standard Time, UTC-06:00)  #    Disclaimer
 Monday, 21 September 2015

Universal-Windows-Platform-SmallI recently made an interesting discovery about Universal Windows Platform apps.

When you build and run them in Release mode they are compiled using the .NET Native compiler, and they stop using mscorlib.

Most of your common .NET types come out of mscorlib. For example:

System.Object, mscorlib, Version=4.0.0.0, Culture=neutral,PublicKeyToken=7ce85d7bea7798e

When you are running UWP code in Debug mode that remains true. But in Release mode the use of mscorlib is replaced by System.Private.CoreLib. For example:

System.Object, System.Private.CoreLib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a

In the vast majority of cases nobody cares about the assembly qualified name of a type – unless you are using reflection, in which case you may easily make this same discovery.

In my case, working on CSLA .NET, this difference posed a real challenge. One of the key features of CSLA is the concept of mobile objects, where object graphs transparently flow (move) across the tiers of your application (between AppDomains, processes, or computers over the network). For this to work, the type names of the objects must be the same in the source and destination environments, whether that be an Android client talking to a full .NET server, or a UWP client talking to that same server.

Fortunately ever since ~2007 and Silverlight’s restrictions on reflection (and the fact that it didn’t support BinaryFormatter or NetDataContractSerializer) CSLA has had its own serializer: MobileFormatter.

MobileFormatter has some serious advantages over BinaryFormatter and the NDCS, most notably it works across all platforms in a consistent manner, as well as minimizing the use of reflection and providing substantial control over the format of the byte stream transferred over the network.

In this scenario that last point is important, because I was easily able to enhance MobileFormatter to translate any assembly qualified type name that uses mscorlib or System.Private.CoreLib so the assembly name is an arbitrary text code. I chose /n. The full assembly name becomes /n during serialization, and that code becomes the full assembly name during deserialization.

The result is that types flow between UWP and all other platforms (.NET, Xamarin, etc.) transparently - as always. As a bonus this change reduces the number of bytes transferred over the wire because the full assembly name isn't in the byte stream, just this short code.

I found that benefit to be compelling enough that while I was changing MobileFormatter to solve the mscorlib issue I also added code to translate the CSLA assembly name to /c in the same manner.

In the future I may look at ways to translate user-created assembly names (your business assemblies) into short codes as well, as that would save a lot of bytes on the wire.

Monday, 21 September 2015 15:47:28 (Central Standard Time, UTC-06:00)  #    Disclaimer
 Wednesday, 16 September 2015

Steps to repro the issue described in this github issue:

https://github.com/MarimerLLC/csla/issues/428

1. Pull the csla repo from
https://github.com/rockfordlhotka/csla.git

a. Switch to the NuGet-uwp branch
clip_image001

2. Open <root>\csla\Source\csla.build.sln

a. Build Release | All CPU
clip_image002

b. Don’t worry about the Xamarin projects – they don’t matter for this issue

c. Build results will be in <root>\csla\bin

i. including the problematic rd.xml files for the UWP projects

3. Open PowerShell, cd to <root>\csla\NuGet

a. Run ‘Build All.ps1’ /prerelease:Beta3

b. Run consolidatepackages.bat

4. Open <root>\csla\Samples\ProjectTracker\ProjectTracker.sln

a. Add a NuGet package source to <root>\Packages, for example:
clip_image004

b. Build Debug | All CPU

i. Ignore the async method lacks await warning – this is a testing artifact

ii. Ignore the warnings about our analyzers (unless you know how to fix them – this analyzer via NuGet stuff is challenging at best!!!!)

iii. You should end up with a build error:

Severity

Code

Description

Project

File

Line

Error

 

Payload contains two or more files with the same destination path 'Csla\Properties\Csla.Uwp.rd.xml'. Source files: C:\Users\Rockford\.nuget\packages\CSLA-Core\4.6.172-Beta3\lib\uap10.0\Csla\Properties\Csla.Uwp.rd.xmlC:\Users\Rockford\.nuget\packages\CSLA-UWP\4.6.172-Beta3\lib\uap10.0\Csla\Properties\Csla.Uwp.rd.xml

ProjectTracker.Ui.UWP

   

Wednesday, 16 September 2015 11:00:21 (Central Standard Time, UTC-06:00)  #    Disclaimer
 Thursday, 27 August 2015

csla win8_fullThis is a NuGet only release, we no longer supply an msi installer

Release details on NuGet: https://github.com/MarimerLLC/csla/releases/tag/v4.6.100

Supported platforms:

  • .NET 4, 4.5, 4.6
  • Android (Xamarin)
  • iOS (Xamarin)
  • UWP (Windows 10)
  • WinRT and WinRT Phone (Windows 8.1 and Phone 8.1)

Major changes:

  • Updated to the final release of Windows 10 and the UWP SDK
  • This and all future releases will be via NuGet only (no more msi installer)
  • Removes support for Silverlight and Windows Phone 8 (Silverlight)
  • Adds support for .NET 4.6
  • Adds support for UWP (though today NuGet deploys the WinRT assemblies for UWP projects)
  • Updates iOS and Android to the latest Xamarin versions
  • Move nearly all code files into shared projects
  • WinRT, iOS, Android, UWP all now use the exact same code files as .NET in every case - which is where a lot of the risk comes from because I may or may not have gotten all the compiler directives fixed up correctly.
  • Add analyzers for Visual Studio 2015 and .NET 4.6 projects
Thursday, 27 August 2015 08:40:34 (Central Standard Time, UTC-06:00)  #    Disclaimer
On this page....
Search
Archives
Feed your aggregator (RSS 2.0)
June, 2017 (1)
May, 2017 (1)
April, 2017 (2)
March, 2017 (1)
February, 2017 (2)
January, 2017 (2)
December, 2016 (5)
November, 2016 (2)
August, 2016 (4)
July, 2016 (2)
June, 2016 (4)
May, 2016 (3)
April, 2016 (4)
March, 2016 (1)
February, 2016 (7)
January, 2016 (4)
December, 2015 (4)
November, 2015 (2)
October, 2015 (2)
September, 2015 (3)
August, 2015 (3)
July, 2015 (2)
June, 2015 (2)
May, 2015 (1)
February, 2015 (1)
January, 2015 (1)
October, 2014 (1)
August, 2014 (2)
July, 2014 (3)
June, 2014 (4)
May, 2014 (2)
April, 2014 (6)
March, 2014 (4)
February, 2014 (4)
January, 2014 (2)
December, 2013 (3)
October, 2013 (3)
August, 2013 (5)
July, 2013 (2)
May, 2013 (3)
April, 2013 (2)
March, 2013 (3)
February, 2013 (7)
January, 2013 (4)
December, 2012 (3)
November, 2012 (3)
October, 2012 (7)
September, 2012 (1)
August, 2012 (4)
July, 2012 (3)
June, 2012 (5)
May, 2012 (4)
April, 2012 (6)
March, 2012 (10)
February, 2012 (2)
January, 2012 (2)
December, 2011 (4)
November, 2011 (6)
October, 2011 (14)
September, 2011 (5)
August, 2011 (3)
June, 2011 (2)
May, 2011 (1)
April, 2011 (3)
March, 2011 (6)
February, 2011 (3)
January, 2011 (6)
December, 2010 (3)
November, 2010 (8)
October, 2010 (6)
September, 2010 (6)
August, 2010 (7)
July, 2010 (8)
June, 2010 (6)
May, 2010 (8)
April, 2010 (13)
March, 2010 (7)
February, 2010 (5)
January, 2010 (9)
December, 2009 (6)
November, 2009 (8)
October, 2009 (11)
September, 2009 (5)
August, 2009 (5)
July, 2009 (10)
June, 2009 (5)
May, 2009 (7)
April, 2009 (7)
March, 2009 (11)
February, 2009 (6)
January, 2009 (9)
December, 2008 (5)
November, 2008 (4)
October, 2008 (7)
September, 2008 (8)
August, 2008 (11)
July, 2008 (11)
June, 2008 (10)
May, 2008 (6)
April, 2008 (8)
March, 2008 (9)
February, 2008 (6)
January, 2008 (6)
December, 2007 (6)
November, 2007 (9)
October, 2007 (7)
September, 2007 (5)
August, 2007 (8)
July, 2007 (6)
June, 2007 (8)
May, 2007 (7)
April, 2007 (9)
March, 2007 (8)
February, 2007 (5)
January, 2007 (9)
December, 2006 (4)
November, 2006 (3)
October, 2006 (4)
September, 2006 (9)
August, 2006 (4)
July, 2006 (9)
June, 2006 (4)
May, 2006 (10)
April, 2006 (4)
March, 2006 (11)
February, 2006 (3)
January, 2006 (13)
December, 2005 (6)
November, 2005 (7)
October, 2005 (4)
September, 2005 (9)
August, 2005 (6)
July, 2005 (7)
June, 2005 (5)
May, 2005 (4)
April, 2005 (7)
March, 2005 (16)
February, 2005 (17)
January, 2005 (17)
December, 2004 (13)
November, 2004 (7)
October, 2004 (14)
September, 2004 (11)
August, 2004 (7)
July, 2004 (3)
June, 2004 (6)
May, 2004 (3)
April, 2004 (2)
March, 2004 (1)
February, 2004 (5)
Categories
About

Powered by: newtelligence dasBlog 2.0.7226.0

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

© Copyright 2017, Marimer LLC

Send mail to the author(s) E-mail



Sign In