MSix Packaging Project

Deployment is hard. Arguably, deployment is the reason the web apps have won over desktop apps. I’ve seen applications written as web apps that would have been easier, faster and more reliable written as desktop applications; however, the deployment problem is such a big factor, that these days, you have to have such a compelling reason to create a desktop application that they are almost unheard of.

With .Net Core 3, came a new attempt from Microsoft to make this whole deployment process easier. MSix allows you to take a Winforms or WPF application, and package it up in a very similar way to that used for UWP. You can then deploy these to the Windows Store; or, you can self host them, and deploy them from your own web-site.

Using an MSix does solve a number of deployment problems; for example, it pretty much picks up where ClickOnce left off. It guarantees that you’re not installing anything horrendous on your machine, because the packaging process sandboxes the application.

However, it is, by no means, perfect. This post covers how you can create a side-loaded deployment project. As a disclaimer, I used this post from James Montemagno as a base for this; however, there were a couple of parts where I got stuck with his post, so hopefully this fills in some gaps.

The post assumes that you have a WPF or WinForms application that you wish to deploy, and that you’re using Visual Studio.

1. Set runtime identifier:

<PropertyGroup>
    <!--Regular Settings-->
    <Platforms>AnyCPU;x64;x86</Platforms>
    <RuntimeIdentifiers>win-x64;win-x86</RuntimeIdentifiers>
  </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
    <PlatformTarget>x64</PlatformTarget>
  </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x86'">
    <PlatformTarget>x86</PlatformTarget>
  </PropertyGroup>

2. Create new Windows Application Packaging Project in your solution:

3. Name project:

4. Pick a minimum and target version:

5. Add reference to the project to deploy. That is, reference the project that you wish to be deployed by your packaging application:

6. Create App Packages (if you were publishing to the store, and you’d already created the app in the store, this is where you would diverge from these instructions):

7. Select Sideloading (if you were registering a store app for the first time, this is where you would diverge from these instructions):

8. Create a test certificate:

9. Set-up version and target platforms:

10. Create a distribution web site (https://docs.microsoft.com/en-us/windows/msix/app-installer/web-install-azure):

Contrary to what this screenshot may lead you to believe, don’t bother doing anything to it just yet – just create it so that you have the URL.

11. Deploy the app packages (you’ll need the URL from above):

12. Once you’ve published the app, install the test certificate to Local Machine -> Trusted Root Certificates. Obviously, were you to do this in real life, you’d need a kosher certificate.

13. FTP the entire contents of the AppPackages directory to the site. To find the FTP details, select the deployment centre:

From here, select FTP:

Once you select FTP, a Dashboard button will appear at the bottom of the screen, select that, and the FTP credentials should appear:

14. Create the default.html, as shown above; clearly, you’ll need your own link, but the format should be the same as mine.

That’s it – you should have a web-site with a link that allows you to install a desktop application locally (albeit you’ll need the certificate installed on the local machine).

References

https://montemagno.com/distributing-a-net-core-3-wpf-and-winforms-app-with-msix/

https://docs.microsoft.com/en-gb/windows/msix/app-installer/web-install-azure

https://www.advancedinstaller.com/install-test-certificate-from-msix.html

Policy Server with Asp.Net Core

It took me a while to collate my notes for this; hopefully this will be the first in a vaguely related series on using Policy Server.

Policy Server is a product from a company called Solliance, allowing you to control authorisation within your application (as opposed to authentication – the same company produces a sister product, called Identity Server). The idea is that, the user is authenticated to determine they are who they say they are, but then authorised to use certain parts of the application, or to do certain things.

This post discusses setting up the open source version of Policy Server. There is a commercial version of this.

The ReadMe on the above GitHub page is quite extensive, however, when I was trying this out, I had some areas that I thought weren’t too clear. This post will explain that to me in the future, should I become unclear again (a common occurrence when you get to a certain age!)

It’s worth bearing in mind that authorisation and authentication need to be done on the server; whilst you may choose to also do that on the client, the code on the client is, well, on the client! If you have some Javascript code sat in the web browser that’s stopping me from seeing the defence plans, then that’s just not secure enough.

Installing and Configuring Policy Server

The first step here is to install the NuGet package:

Install-Package PolicyServer.Local

Next, add Policy Server in startup.cs:

    public void ConfigureServices(IServiceCollection services)
    {
            services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);

            // In production, the React files will be served from this directory
            services.AddSpaStaticFiles(configuration =>
            {
                configuration.RootPath = "ClientApp/build";
            });

            services.AddPolicyServerClient(Configuration.GetSection("Policy"));
    }

Amazingly, at this stage, you’re basically done. The next stage is to add the rules into the appsettings.json. There is an example on the page above, but here’s a much simpler one:

  "Policy": {
    "roles": [
      {
        "name": "salesmanager",
        "subjects": [ "1" ]
      },
      {
        "name": "driver",
        "subjects": [ "2" ]
      }
    ],
    "permissions": [
      {
        "name": "ViewRoutes",
        "roles": [ "driver" ]
      },
      {
        "name": "CreateSalesOrder",
        "roles": [ "salesmanager" ]
      },
      {
        "name": "Timesheet",
        "roles": [ "salesmanager", "driver" ]
      }
    ]
  }

This is, in fact, the part that I didn’t feel was clear enough in the GitHub readme. What, exactly, are “subjects”, and how do I associate them to anything useful? I’ll come back to this shortly, but first, let’s see the rules that we have set up here:

The Sales Manager can create a sales order, and complete their timesheet.

The Driver can view routes and complete their timesheet.

The Sales Manager can not view routes; nor can the driver create a sales order.

Add Policy Server to a Controller

The next stage is to inject Policy Server into our controller. For the home controller, all you need to do is inject IPolicyServerRuntimeClient:

        private readonly IPolicyServerRuntimeClient _policyServerRuntimeClient;

        public HomeController(IPolicyServerRuntimeClient policyServerRuntimeClient)
        {
            _policyServerRuntimeClient = policyServerRuntimeClient;
        }

This can now be used anywhere in the controller. However, for testing purposes, let’s just circle back round to the subject question. The subject is the identity of the user. You may have noticed that I’ve started this post with PolicyServer, so I don’t have any authentication in place here. However, for testing purposes, we can force our user to a specific identity.

Let’s override the Index method of the HomeController:

        public async Task<IActionResult> Index()
        {
            var identity = new ClaimsIdentity(new Claim[]
            {
                new Claim("sub", "2"),
                new Claim("name", "TestUser")
            }, "test");

            User.AddIdentity(identity);

            var homeViewModel = await SecureViewModel();
            return View(homeViewModel);
        }

We’ll come back to the ViewModel business shortly, but let’s focus on the new ClaimsIdentity; notice that the “sub” (or subject) refers to the Subject ID of the driver above. So what we’ve done is created a driver!

The SecureViewModel method returns a ViewModel (which, as you can see, is passed to the view); let’s see what that might look like:

        public async Task<HomeViewModel> SecureViewModel()
        {
            var homeViewModel = new HomeViewModel();            
            homeViewModel.ViewRoutes = await _policyServerRuntimeClient.HasPermissionAsync(User, "ViewRoutes");
            homeViewModel.CreateSalesOrder = await _policyServerRuntimeClient.HasPermissionAsync(User, "CreateSalesOrder");
            homeViewModel.Timesheet = await _policyServerRuntimeClient.HasPermissionAsync(User, "Timesheet");

            return homeViewModel;
        }

You can play about with how this works by altering the “sub” claim.

How does this fit into Identity Server (or an identity server such as Azure B2C)?

The identity result of the authentication, should map to the “sub” claim. In some cases, it’s “nameidentitifier”. Once you’ve captured that, you’ll need to store that reference against the user record.

That’s all very well for testing, but when I use this for real, I want to plug my data in from a database

The first thing you’ll need to do is to ‘flatten’ the data. this StackOverflow question was about the best resource I could find for this, and it gets you about 90% of the way there. I hope to come back to that, and linking this in with Asp.Net Core Policies in the next post.

References

https://auth0.com/blog/role-based-access-control-rbac-and-react-apps/

https://github.com/IdentityServer/IdentityServer4/issues/2968

https://stackoverflow.com/questions/55450393/persist-entitys-in-database-instead-of-appsettings-json

https://stackoverflow.com/questions/55450393/persist-entitys-in-database-instead-of-appsettings-json

Simple binding in Blazor

A while back, I asked on Dev about moving my blog from WordPress to … well, not WordPress anymore. My main critera was to Markdown instead of whatever the WordPress format is called. The main issue being that you need to replace the code tags.

I resolved to create a tool to do it for me. I’m doing so in Blazor.

The first task was to create a very simple data binding scenario, so I could handle all the view logic in the View Model. I’ve previously written about using view models. This post covers the scenario where you want to bind text boxes and a button.

Let’s see the View Model first:

    public class MainViewModel
    {
        public string WpText { get; set; }
        public string MdText { get; set; }

        public void ConvertText()
        {
            MdText = $"Converted {WpText}";
        }
    }

Okay, so we have two strings, and a method that populates the second string with the first. As per the linked post, the plumbing for the view model is very simple; first, it’s registered in ConfigureServices:

        public void ConfigureServices(IServiceCollection services)
        {
            services.AddTransient<MainViewModel, MainViewModel>();
        }

Then it’s injected into the Razor view:

@page "/"
@inject ViewModels.MainViewModel MainViewModel

In fact, the next part is much simpler than I thought it would be. To bind a view model property to the view, you just use the syntax bind:

<div class="container">
    <div class="row">
        <div class="form-group col-md-6">
            <label for="WpText">Wordpress Text</label>
            <input type="text" @[email protected] class="form-control" id="WpText" name="WpText"/>
        </div>

        <div class="form-group col-md-6">
            <label for="MdText">Markdown</label>
            <input type="text" @[email protected] class="form-control" id="MdText" name="MdText"/>
        </div>
    </div>
    <div class="row">
        <div class="form-group col-md-12">
            <input type="button" value="Convert" @[email protected](() => MainViewModel.ConvertText()) class="form-control" id="Submit" />
        </div>
    </div>
</div>

Just to point out one thing that tripped me up before I leave this: the event handlers that relate to Blazor must be prefixed with an at symbol (@).

References

https://www.nativoplus.studio/blog/blazor-data-binding-2/

Creating a Xamarin Forms Project – Android SDK Tools

I’m quite new to Xamarin Forms; I’ve managed to get projects working before now, but I find myself stumbling through the same problems again and again. This is one such issue – so, hopefully, now I will come across my own article first!

The Problem

You create a new Xamarin Forms app, press F5 and you get an error similar to this:

Xamarin.Android for Visual Studio requires Android SDK. Please click here to configure.

If you double click this, it should launch the Android SDK Manager.

The Solution

The problem is, in fact, that there are many Android SDKs; so you need to install the correct ones for the systems that you’re targeting. Start with the SDK Manager; if it hasn’t already launched, then launch that here:

Next, have a look in your Xamarin output (that’s the standard output window, just select output from Xamarin in the drop-down):

Okay, so now you know what’s missing. We should now be able to find those versions of the Build Tools in the SDK Manager:

Once you’ve made the changes, select “Apply Changes” at the bottom.

It would be nice if that was it; however, you may have to restart Visual Studio before it realises what you’ve done.

An ADR Visual Studio Tool – Part 1 – Creating a Visual Studio Extension to Scrape the Solution and List all Items, Including Solution Items and Solution Folders

A while back, a colleague of mine brought the concept of ADRs to my attention. The idea being that, when you make a decision on a project, you write it down, but you do so inside the code base, and check it into the source control system.

Even in the days when people believed writing long functional specifications was a good idea, having documentation that married up to the code it documented was a distant dream. Typically, you’d spend about a week writing a spec, and the minute you wrote the first line of code, the document was, essentially, considered dead (and only ever referred back to where the customer disputed what had been delivered).

Since I’ve never written a Visual Studio Extension, but always thought it would be a cool idea, I had an idea to start with this. My thought was that I could build something that would extract the ADRs from the main codebase. This isn’t one of those posts where I have a completed solution, and I’m just documenting it… it’s more of an ongoing journey… which may result in the conclusion that this either doesn’t make sense, isn’t feasible, or has already been done.

I’m going to upload the progress so far to this GitHub repo.

In this first post, we’ll create an extension capable of viewing the project it’s in.

Step 1 – Install the SDK

To do any extension development, you need to install the SDK – you can do this through the Visual Studio Installer:

Step 2 – Create a new (VSIX) project

VS Extensions are referred to as VSIX, because that’s the extension of the deployable product.

Step 3 – Add a new Tool Window and Test

Add a new Item (right click project -> add new item), and select the Tool Window:

There is no need to do any plumbing here – any eligible extension types in the solution will be compiled and used – try pressing F5 now. You should get a version of Visual Studio to debug:

As you can see, I’ve been here before. For the purposes of testing, I’ve set-up a convoluted project:

The reason for this will become clear shortly, for now, just launch the tool window that you created (View -> Other Windows -> Tool Window 1 (or whatever you called it):

Step 4 – Add some code to the Tool Window

For the purpose of this first stage, we’ll just analyse the project structure. When it’s finished, I’d like it to be able to identify the ADR docs based on a configurable location but, for now, let’s just show how many projects and files we have. For now, we won’t change anything, let’s just hook into the button click of the subtle button in the screenshot above:

        private async void button1_Click(object sender, RoutedEventArgs e)
        {
            await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync();
            var dte = (DTE)Package.GetGlobalService(typeof(DTE));            

            var sln = Microsoft.Build.Construction.SolutionFile.Parse(dte.Solution.FullName);
            projectsText.Text = $"{sln.ProjectsInOrder.Count.ToString()} projects";

            foreach (Project p in dte.Solution.Projects)
            {
                projectsText.Text += $"{Environment.NewLine} {p.Name} {p.ProjectItems.Count}";
            }
        }

SwitchToMainThreadAsync is because any interaction with the solution needs to be on the main thread. After that, we parse the solution file and output the name and items in each “project”:

As you can see, it classes each top level folder as a solution project, which will be ideal for us.

Summary

In this post, we’ve seen how to create a Visual Studio Extension, and how to trawl the current solution and projects. In the next post, we’ll try to extract some ADR specific stuff.

References

https://docs.microsoft.com/en-us/visualstudio/extensibility/installing-the-visual-studio-sdk?view=vs-2017

https://msdn.microsoft.com/en-us/library/ms973240.aspx?f=255&MSPPError=-2147217396

https://docs.microsoft.com/en-us/visualstudio/extensibility/starting-to-develop-visual-studio-extensions?view=vs-2017

http://www.visualstudioextensibility.com/articles/packages/

Creating a Car Game in React – Part 6 – Adding High Scores

This is the sixth post of a series that starts here.

As with previous posts, if you wish to download the code, it’s here; and, as with previous posts, I won’t cover all the code changes here, so if you’re interested, then you should download the code.

In this post, we’re going to create a High Score table. We’ll create an Azure function as the server, and we’ll store the scores themselves in Azure Tables.

Let’s start with the table.

Create a new storage account in Azure, then add an Azure Table to it:

You’ll see a sign trying to persuade you to use Cosmos DB here. At the time of writing, using Cosmos was considerably more expensive than Table Storage. Obviously, you get increased throughput, distributed storage, etc with Cosmos. For this, we don’t need any of that.

Create a new table:

An Azure table is, in fact, a No SQL offering, as you have a key, and then an attribute – the attribute can be a JSON file, or whatever you choose. In our case, we’ll set the key as the user name, and the score as the attribute.

Once you’re created your table storage, you may wish to use the Storage Explorer to create the tables, although that isn’t necessary.

Finally, you’ll need to add a CORS rule:

Obviously, this should actually point to the domain that you’re using, rather than a blanket ‘allow’, but it’ll do for testing.

Adding a username

Before we can store a high score, the user needs a username. Let’s add one first.

In game status, we’ll add a text box:

<div style={containerStyle}>
	<input type='text' value={props.Username}
	onChange={props.onChangeUsername} />
</div>

The state is raised to the main Game.jsx:

<GameStatus Lives={this.state.playerLives} 
	Message={this.state.message} 
	Score={this.state.score} 
	RemainingTime={this.state.remainingTime}
	Level={this.state.level}
	Username={this.state.username} 
	onChangeUsername={this.onChangeUsername.bind(this)} 
/>

And onChangeUsername is here:

onChangeUsername(e) {
	this.updateUserName(e.target.value);
}

updateUserName(newUserName) {
	this.setState({
		username: newUserName
	});
}

Update High Score

We’ll create an Azure Function to update the table. In Visual Studio, create a new Windows Azure Function App (you will need to install the Azure Workload if you haven’t already):

You’ll be asked what the trigger should be for the function: we’ll go with HttpTrigger. This allows us to call our function whenever we please (rather than the function, being say scheduled.) Next, we’ll need to install a NuGet package into our project to let us use the Azure Storage Client:

Install-Package WindowsAzure.Storage

We need some access details from Azure:

Creating the Functions

We’re actually going to need two functions: update and retrieve (we won’t be using the retrieve in this post, but we’ll create it anyway). Let’s start with a helper method:

    public static class StorageAccountHelper
    {
        public static CloudStorageAccount Connect()
        {
            string accountName = Environment.GetEnvironmentVariable("StorageAccountName");
            string accountKey = Environment.GetEnvironmentVariable("StorageAccountKey");

            var storageAccount = new CloudStorageAccount(
                new Microsoft.WindowsAzure.Storage.Auth.StorageCredentials(
                    accountName, accountKey), true);
            return storageAccount;
        }
    }

For testing purposes, add the account name and key into the local.settings.json:

{
  "IsEncrypted": false,
  "Values": {
    "AzureWebJobsStorage": "UseDevelopmentStorage=true",
    "FUNCTIONS_WORKER_RUNTIME": "dotnet",
    "StorageAccountName": "pcmtest2",
    "StorageAccountKey": "C05h2SJNQOXE9xYRObGP5sMi2owfDy7EkaouClfeOSKRdijyTQPh1PIJgHS//kOJPK+Nl9v/9BlH4rleJ4UJ7A=="
  }
}

The values here are taken from above – where we copied the access keys from Azure (whilst these keys are genuine keys, they will be changed by the time the post is published – so don’t get any ideas!

First, let’s create a function to add a new high Score:

        [FunctionName("AddHighScores")]
        public static async Task<IActionResult> Run(
            [HttpTrigger(AuthorizationLevel.Function, "post", Route = null)] HttpRequest req,
            ILogger log)
        {
            log.LogInformation("C# HTTP trigger function processed a request.");

            var newScore = new HighScore(req.Query["name"], int.Parse(req.Query["score"]));            

            var storageAccount = StorageAccountHelper.Connect();

            CloudTableClient client = storageAccount.CreateCloudTableClient();
            var table = client.GetTableReference("HighScore");

            await table.ExecuteAsync(TableOperation.InsertOrReplace(newScore));

            return new OkResult();
        }

If you’ve seen the default example of this function, it’s actually not that different: it’s a POST method, we take the name and score parameters from the query string, build up a record and add the score. The function isn’t perfect: any conflicting names will result in overwritten score, but this is a copy of a spectrum game – so maybe that’s authentic!

The second function is to read them:

        [FunctionName("GetHighScores")]
        public static async Task<IList<HighScore>> Run(
            [HttpTrigger(AuthorizationLevel.Function, "get", Route = null)] HttpRequest req,
            ILogger log)
        {
            log.LogInformation("C# HTTP trigger function processed a request.");

            var storageAccount = StorageAccountHelper.Connect();

            CloudTableClient client = storageAccount.CreateCloudTableClient();
            var table = client.GetTableReference("HighScore");
            var tq = new TableQuery<HighScore>();
            var continuationToken = new TableContinuationToken();
            var result = await table.ExecuteQuerySegmentedAsync(tq, continuationToken);
            
            return result.Results;
        }

All we’re really doing here is reading whatever’s in the table. This might not scale hugely well, but again, for testing, it’s fine. The one thing to note here is ExecuteQuerySegmentedAsync: there seems to be very little documentation around on it; and what there is seems to refer to ExecuteQueryAsync (which, as far as I can tell, doesn’t, or at least, no longer, exists).

Let’s run the Azure function locally and see what happens:

As you can see, Azure helpfully gives us some endpoints that we can use for testing. If you don’t have a copy already, then download Postman. Here you can create a request that calls the function.

I won’t go into the exact details of how Postman works, but the requests might look something like this:

http://localhost:7071/api/AddHighScores?name=test2&score=19
http://localhost:7071/api/GetHighScores?10

To prove to yourself that they are actually working, have a look in the table.

There is now an online Storage Explorer in the Azure Portal. Details of the desktop version can be found in this post.

Update High Score from the Application

Starting with adding the high score, let’s call the method to add the high score when the player dies (as that’s the only time we know what the final score is):

playerDies() { 
    this.setState({
        playerLives: this.state.playerLives - 1,
        gameLoopActive: false
    });

    if (this.state.playerLives <= 0) {
        this.updateHighScore();
        this.initiateNewGame();
    } else {
        this.startLevel(this.state.level);
    }

    this.repositionPlayer();
    this.setState({ 
        playerCrashed: false,
        gameLoopActive: true
    });
}

The updateHighScore function looks like this:

updateHighScore() {
	fetch('http://localhost:7071/api/AddHighScores?name=' + this.state.username + '&score=' + this.state.score, {
		method: 'POST'
	}); 
}

Note (obviously) that here I’m updating using my locally running instance of the Azure Function.

And that’s it – we now have a score updating when the player dies. Next we need to display the high scores – that’ll be the next post.

References

https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch

https://facebook.github.io/react-native/docs/network

Using Blazor Components

Imagine that you’re writing a Blazor application – maybe it’s similar to this one. Now, imagine that you have a large chunk of HTML in your main view. You might think: I wish I was using React, then I could separate this into its own component.

You can also do this in Blazor. Here’s how.

Components in Blazor

Let’s start with moving your code. The first step is to cut your HTML and paste it into a new Razor Component:

The format of your new component, from scratch, will be:

&lt;h3&gt;Component Name&lt;/h3&gt;

@code {

}

Your existing code should go beneath, or instead of:

&lt;h3&gt;Component Name&lt;h3&gt;

Parameters

The @code section allows you to put all kinds of crazy C# code in a code behind type model – so you probably don’t want to use that, except for passing parameters; for example:

@code {
    [Parameter]
    private string MyParameter { get; set; }
}

This allows you to pass a string into your component; for example (in your main view):

&lt;MyComponent MyParameter=&quot;test&quot; /&gt;

Complex Parameters

So far so good. But what if you need a complex type? You could, for example, pass a View Model into your component:

[Parameter]
private MyViewModel MyViewModel { get; set; }

You can pass this into the component as though it were a primitive type:

&lt;MyComponent MyViewModel=&quot;@MyViewModel&quot; /&gt;

This means that you can lift and shift the code with no changes.

Using External Namespaces

As with standard C#, you can access anything within the current namespace. Should you need any classes that are not in your current namespace, you can declare them at the top of the file, like this:

@using MVVMShirt

&lt;h3&gt;My Component&lt;/h3&gt;

Summary

Blazor is still in its infancy, but hopefully, adding actual code to these @code sections will become as frowned upon as code-behind.

React Tips: 4 – Propagating State

One thing that’s worth remembering about React is that when you’re updating state, only the Render method gets re-executed.

It’s easy (as I did) to fall into the trap of doing something like this:

    const myStyle = {
        background: this.props.backgroundFlag == 1 ? "blue" : "yellow",
        display: 'inline-block',
        height: '100%',
    }

    public render() {
        return <>
            <div className="myDiv" style={myStyle}>
        </>
    }

Imagine that this.props.backgroundFlag is actually the state of the containing component; when you change it, you would expect your component to reflect your change. However, in the case above, what will actually happen is nothing – because only the render method is re-evaluated when the virtual DOM changes.

To correct this, you need whatever needs to be re-evaluated inside the render method; for example:

    public render() {
	    const myStyle = {
	        background: this.props.backgroundFlag == 1 ? "blue" : "yellow",
	        display: 'inline-block',
	        height: '100%',
	    }

        return <>
            <div className="myDiv" style={myStyle}>
        </>
    }

UWP using Unity and EF Core and Sqlite

If you intent to use IoC with a UWP application, there are a lot of options. Most of them come with MVVM packages, like MVVM Cross. These are excellent packages – I’ve used MVVM Cross and MVVM Light myself and can highly recommend them.

However, if you didn’t want all that baggage, how would you implement a very simple IoC system in UWP?

In this example, I’m using Unity, however, I believe this will work for any IoC container. I’m also using the IoC container to resolve a View Model – but you don’t need to use View Models (although IMHO, it makes your life so much easier.)

Secondly, I’ll be showing how to use Ef Core with your UWP app. This sounds very trivial, but there’s a bit of fiddling about to get it to work.

Entity Framework Core Set-up

In my project, I’ve separated the data access layer, but you don’t need to do that. Start by creating a data context:

public class MyDbContext : DbContext
{
    public DbSet<Data> MyData { get; set; }
 
    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        optionsBuilder.UseSqlite("Data Source=mydata.db");
    }
}

You’ll need the following packages:

Install-Package Microsoft.EntityFrameworkCore
Install-Package Microsoft.EntityFrameworkCore.Design
Install-Package Microsoft.EntityFrameworkCore.Tools
Install-Package Microsoft.EntityFrameworkCore.Sqlite

You’ll also need to create a console application – why? Because you can’t use any of the EF tools with UWP! If you set your UWP app as the start-up and create your migration, you’ll get this error:

Startup project ‘SendMessage.UWP’ is a Universal Windows Platform app. This version of the Entity Framework Core Package Manager Console Tools doesn’t support this type of project.

Set the console app as startup and add the migration:

Add-Migration "InitialDbCreate"

Don’t worry about updating the DB, we’ll get the app to do that (it just can’t use the tools, but it can perform a migration.)

UWP

From a new, blank, UWP app; in app.xaml.cs:

sealed partial class App : Application
{
    public static IUnityContainer Container { get; set; } = new UnityContainer();
 
    /// <summary>
    /// Initializes the singleton application object.  This is the first line of authored code
    /// executed, and as such is the logical equivalent of main() or WinMain().
    /// </summary>
    public App()
    {
        this.InitializeComponent();
        this.Suspending += OnSuspending;
 
        using (var db = new MyDbContext())
        {
            db.Database.Migrate();
        }
        
        Container.RegisterType<MainViewModel>();
    }

We’re creating a static UnityContainer in App.Xaml.cs. Register the type (in this case a MainViewModel, but it could as easily be an interface).

The next step is resolving the interface. Unfortunately, because of the way that the UWP navigate works, Unity won’t perform constructor injection for us. A little trick around this is to create a parameterless constructor and have that call the injected constructor. It’s not quite constructor injection, but semantically it’s the same thing. Here’s the code from my MainPage.xaml.cs:

public sealed partial class MainPage : Page
{
    public MainPage() : this(App.Container.Resolve<MainViewModel>()) { }
 
    public MainPage(MainViewModel mainViewModel)
    {
        this.InitializeComponent();
 
        this.DataContext = mainViewModel;
    }
}

That’s pretty much it; you can run this, and it’ll migrate the data, and resolve the dependency.

References

https://docs.microsoft.com/en-us/ef/core/get-started/uwp/getting-started

React Tips: 3 – Cloning a React Repository

After you clone a React repository, running npm start may give this error:

‘react-scripts’ is not recognized as an internal or external command

The reason, as explained here, is that you need to run:

npm install

This should be run inside the directory that you clone. For example:

git clone https://github.com/pcmichaels/react-demos.git
cd react-demos
npm install
npm start