NET Standard Mobile LOB: Prism, EFCore Sqlite and Validation UWP [1]

Introduction

My first idea was creating the environment with Xamarin but at the moment you cannot compile .NET Standard with Xamarin Forms, I will update the articles when the bugs go away.

Until then I decided to create an NET Standard library that in a near future will be the same for the Xamarin Forms project.

This article makes me really happy because it has been a long way until here, and when NET Standard 2.0 get released our C# world will enter in a new dimension, I assure that.

Situation

At the moment if you are in the world of PCL, and if you have tried to do something with Entity Framework Core Sqlite (EFCSqlite), its development goes directly to NET Standard without having a PCL release. So its being developed for the future.

So the option is right clear for the LOB project, create a NET Standard library that has to contain EFCoreSqlite, Prism.Core, Prism.Windows and System.ComponentModel.Annotations all working together.

And what we do it now? NET Standard 1.4 is the recommended version to use with UWP projects until the release of the 2.0. and with a magic tricks I will show you next you can mix all those libraries in one place.

New solution

Let’s create a new UWP project using .NET Framework 4.6.1:

newuwpproject.JPG

I always use 14393 for UWP on both target and min, but in theory you can use the option you need.

Now let’s create the LOB .NET Standard library:

newstandardproject.JPG

Now comes the first trick, adding fallbacks to .NET Standard to allow adding .NET PCL ‘specific’ libraries.

Unload the Marketing.LOB project and edit the csproj, add the fallbacks like the following:

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <TargetFramework>netstandard1.4</TargetFramework>
    <PackageTargetFallback>$(PackageTargetFallback);portable-monoandroid10+monotouch10+net45+win+win81+wp8+wpa81+xamarinios10</PackageTargetFallback>
    <PackageTargetFallback>$(PackageTargetFallback);uap10.0</PackageTargetFallback>
  </PropertyGroup>

</Project>

If you want you can download from the Nuget library the latest versions or add below the Property Group section, another section:

  <ItemGroup>
    <PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="1.1.1" />
    <PackageReference Include="Prism.Core" Version="6.2.0" />
    <PackageReference Include="Prism.Windows" Version="6.0.2" />
    <PackageReference Include="System.ComponentModel.Annotations" Version="4.3.0" />
  </ItemGroup>

And now compile and it works!. Great

Models

Let’s create a Client really basic model in properties but cool in implementation, create a folder Models in the LOB project and the class Client:

 public class Client : ValidatableBindableBase
    {
        #region Properties
        public int ClientId { get; set; }

        private string name;
        [Required(AllowEmptyStrings = false, ErrorMessage = "NotEmpty")]
        public string Name
        {
            get { return name; }
            set
            {
                SetProperty(ref name, value);
            }
        }

        private string details;
        [NotMapped]
        public string Details
        {
            get { return details; }
            set { SetProperty(ref details, value); }
        }
        #endregion
    }

see that? It is a Prism ValidatableBindableBase with ComponentModel DataAnontations cool! And as you can see I set the Id to ClientId to be automatic with EFCSqlite for the following article.

ViewModel

I have made an effort to keep it pretty simple, create a ViewModels folder in the LOB project and here are the needs of the implementation:

  • Is Loading field (avoids need to validate and show for instance ‘NotEmpty’ in required field textblock).
  • Property Error Event handler to refresh the validation.
  • a Create Command to create the client using EF.
  • a validation method ‘CanCreate’ that checks if it is loading and errors.
public class ClientFormViewModel : BindableBase
    {
        #region Properties and Fields
        public Client Client { get; set; }

        public DelegateCommand Create { get;  }

        private bool isloading = true;
        #endregion

        #region Constructor
        public ClientFormViewModel()
        {
            Client = new Client();
            Create = new DelegateCommand(CreateClient, CanCreate);
            Client.PropertyChanged += Client_PropertyChanged;
            Client.ErrorsChanged += Client_ErrorsChanged;
        }
        #endregion

        #region Validation
        private void Client_ErrorsChanged(object sender, DataErrorsChangedEventArgs e)
        {
            Create.RaiseCanExecuteChanged();
        }

        private void Client_PropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            Create.RaiseCanExecuteChanged();
        }

        private bool CanCreate()
        {
            if (isloading)
            {
                isloading = false;
                return false;
            }

            return Client.Errors.Errors.Count == 0;
        }
        #endregion

        private void CreateClient()
        {
            //To be continue in the next post
        }

    }

Now the validation is linked to the canexecute property of the Create Command.

View

Add the reference of the LOB project in the UWP project and create a folder Views and a Page ‘ClientFormView’.

In this case to simplify I add the viewmodel in the following way:

public sealed partial class ClientFormView : Page
    {
        public ClientFormViewModel ViewModel { get; } = new ClientFormViewModel();

        public ClientFormView()
        {
            this.DataContext = ViewModel;
            this.InitializeComponent();
        }
    }

Inside the Grid of the XAML the following stack panel:

 <StackPanel MaxWidth="360">
            <TextBlock Style="{StaticResource HeaderTextBlockStyle}" Text="Client"/>
            <TextBox Header="Name" x:Name="ClientName" Text="{Binding Client.Name, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
            <TextBlock Text="{Binding Client.Errors[Name][0]}" Foreground="Red" HorizontalAlignment="Right" />

            <TextBox Header="Details" x:Name="ClientDetails" Text="{Binding Client.Description, Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" />

            <Button Command="{x:Bind ViewModel.Create}" Content="Create" HorizontalAlignment="Right" Margin="0,12,0,0"/>
        </StackPanel>

Pretty simple and effective. Until compiled binding has features like not crashing when references are null I have to use classic binding.

Remove the MainPage and make the App rootframe navigate to the new View. Run it and test it writing some text (the button will be enabled) and now delete the text (the button will be disable and the error information will appear).

Here ends the first part of the article. In summary now we can use the standard libraries to make it work without need of workarounds.

In the next chapter I will explain the implementation of EF Core SQLite, creating the database and clients.

Hope you find the article fascinating as I see and if you want, on the right pane, you can donate for some coffee and tea.

Grab the source example from github-mark-64px

Know all about my progress at @juanpaexpedite, hope you enjoy the article.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s