Develop a Blazor project with Visual Studio Code on Mac

Blazor is a new, experimental, framework for develop Single Page Application by using the same framework, library and language: C#. It is really powerful and you can use it on every OS and on every browser that supports WebAssembly. In this post we will see how you can create a project by using MacOS and Visual Studio Code

Create a new project with CLI

The Command Line Interface is the most simple way to create a new project. To create a Blazor project, first of all you need to install the Blazor templates. On Visual Studio Code, open the terminal window by going to View -> Terminal, then write the dotnet new -i Microsoft.AspNetCore.Blazor.Templates::* command:

Install Blazor templates

then, you can simply write the dotnet new blazor command:

Create new Blazor project

The above command download the template files and then execute dotnet restore to download all dependencies. The final project name will be the same of the container folder.

We have created the most simpler project, but you can create four different types of Blazor project:

Command Description
dotnet new blazorhosted Blazor hosted in ASP.NET server
dotnet new blazorlib Blazor Library
dotnet new blazorserverside Blazor Server-side in ASP.NET Core
dotnet new blazor Blazor standalone application

Run your project

Now, you will be able to run the project by simply execute the dotnet run command:

Run a Blazor app on mac

And if something goes wrong…

Be sure to have the latest .NET Core version installed on your development machine. Go to Microsoft Download

How to debug Xamarin and Mono class library with Visual Studio for Mac

Enabling the debugging of Xamarin or Mono class library in Visual Studio for Mac is really very simple and is well described in this page. The only step you need to do is uncheck the Debug project code only; do not step into framework code. in Visual Studio for Mac > Preferences > Debugger:

Visual Studio for Mac Enable Debug

But…

Even though the above page said Xamarin products ship with the source code for Mono’s class libraries, I was unable to execute the debug after uncheck the above descripted option (the step into options doesn’t work). The reason is simple: no source code is available in your machine!

So, to start debugging, you must download the Mono source code. Simply go to the Mono GitHub page, and select the tag related to your local mono version:

Mono tag selection

then, click on Clone or download > Download ZIP on the right side and unzip the file into the following folder: /Library/Frameworks/Xamarin.iOS.framework/Versions/11.6.1.3/src

Finally, rename the folder in mono:

Mono folder

And voilà:

Mono debug

A simple approach to navigation with Model-View-ViewModel in Xamarin.Forms

Model-View-ViewModel is a widely used architectural pattern that helps you to separate UI from presentation logic responsibility. In your ViewModel you can provide data to the View through binding and handle the action by using commands, but what about the navigation? Who is responsible for showing another view?

The following schema show how the View, the ViewModel and the Model interact in the MVVM architecture:


source: https://msdn.microsoft.com/en-us/library/hh848246.aspx

In this post, we’ll see how the MVVM starts the navigation in a straightforward approach, based on the assumption that navigation from ViewModel is a “request of navigation”. The “request of navigation” is sent to the View, the real executor, by using a set of specific delegates.

Show Me The Code

Since in MVVM the ViewModel doesn’t know anything about the View, we need to notify the View when a request for navigation is in place. So, to do this, our implementation provides a ViewModelBase class that, by using a delegate, inform a subscriber (the View) that navigation has been requested.

public class ViewModelBase
{
    ...
    public Func<ViewModelBase, Task> OnNavigationRequest { get; set; }
  
    public Task NavigateTo<TViewModel>(TViewModel targetViewModel) where TViewModel : ViewModelBase
    {
        await OnNavigationRequest?.Invoke(targetViewModel);
    }
}

On the other side, the Page will register the delegate when appearing and will cancel when disappearing:

public class PageBase<TViewModel> : ContentPage, IView<TViewModel> where TViewModel:ViewModelBase,new()
{
    ...
    public TViewModel ViewModel
    {
        get { return GetValue(BindingContextProperty) as TViewModel; }
        set { SetValue(BindingContextProperty, value); }
    }
  
    protected override void OnAppearing()
    {
        base.OnAppearing();
        ViewModel.OnNavigationRequest = HandleNavigationRequest;
    }

    protected override void OnDisappearing()
    {
        base.OnDisappearing();
        ViewModel.OnNavigationRequest = null;
    }
}

So, you avoid getting navigation request when the Page is not active. Last, but not least, the delegate will look similar to the following code:

public class PageBase<TViewModel> : ContentPage, IView<TViewModel> where TViewModel:ViewModelBase,new()
{
    ...
    async Task HandleNavigationRequest(ViewModelBase targetViewModel)
    {
        var targetView = ViewResolver.GetViewFor(targetViewModel);
        targetView.BindingContext = targetViewModel;
        await Navigation.PushAsync(targetView);
    }
}

The ViewResolver is responsible for maps the ViewModel to the View in a 1:1 model:

internal static class ViewResolver
{
    public static Page GetViewFor<TargetViewModel>(TargetViewModel targetViewModel) where TargetViewModel : ViewModelBase, new()
    {
        var targetViewName = targetViewModel.GetType().Name.Replace("ViewModel", "Page");
        var definedTypes = targetViewModel.GetType().GetTypeInfo().Assembly.DefinedTypes;
        var targetType = definedTypes.FirstOrDefault(t => t.Name == targetViewName);
        return Activator.CreateInstance(targetType.AsType()) as Page;
    }
}

Obviously, feel free to write it as you prefer.

Ok, let’s use it!

Now, you will be able to start navigation in ViewModel by using the following code:

public class MyViewModel : ViewModelBase
{
    ...
    public async Task DoSomething()
    {
        ...
        await NavigateTo(new OtherPageViewModel());
    }
}

Cool!

Conclusion

Let me know what do you think about this approach. You like it or you hate it? Anyway, you’ll find full code on my github repository.

Inline variable declaration in C# 7

I like to write clean and small code, who don’t want? The C# team is doing a lot of works in this direction. One of the recent features that I like is the inline variable declaration with C# 7. What do I mean? Let’s see the code. Think about a TrySomething method, something about the DateTime.TryParse, you write:

DateTime result;
if (DateTime.TryParse(input, out result))
    DoSomething(result);
else
    Console.WriteLine("Can't parse DateTime");

the new feature will enable you to write something like this:

if (DateTime.TryParse(input, out DateTime result))
    DoSomething(result);
else
    Console.WriteLine("Can't parse DateTime");

Really cool!

How the Xamarin Live Player works with Visual Studio for Mac

Since a picture is worth a thousand of words, this time I preferred to made a video to show how the new Xamarin Live Player works with Visual Studio for Mac. Enjoy!

Xamarin Dev Days @ Potenza

Last friday, thanks to JetBit and to my friend Massimo Bilancia, DotNetSide has organized the first Xamarin Dev Days in Potenza, Basilicata, Italy. What a great day! Meet people, make networking, share development experience in a wonderful location is always the best way to spend a day.

Here, some pictures of the day:

[ngg_images source=”galleries” container_ids=”1″ sortorder=”52,11,41,1,21,31″ display_type=”photocrati-nextgen_basic_slideshow” gallery_width=”600″ gallery_height=”400″ cycle_effect=”fade” cycle_interval=”5″ show_thumbnail_link=”0″ thumbnail_link_text=”[Show thumbnails]” order_by=”sortorder” order_direction=”ASC” returns=”included” maximum_entity_count=”500″] 

Thanks to all the attendees!!!

Next stop: april 20 @ bari

Gestire comportamenti specifici della View in Xamarin.Forms

La chiara e netta separazione tra la UI e l’application logic è il concetto che sta alla base del pattern MVVM. Molte volte, però, non è semplice capire distinguere le responsabilit , almeno in termini di rappresentazione della UI. Se devo cambiare un colore in base al contenuto, è il ViewModel che lo decide? Dove indico il colore?

Tendenzialmente saremo portati ad aggiungere una propriet nel ViewModel con l’indicazione del colore da visualizzare. E magari definiamo come tipo della propriet l’enum Xamarin.Forms.Color. Sebbene semplice, questo approccio è sbagliato perchè assegna al ViewModel una responsabilit della View, oltre al rischio di non rendere il ViewModel compatibile se questo deve essere reso riutilizzabile in diverse piattaforme (non Xamarin.Forms).

Quindi?

Il ViewModel si deve limitare a riportare il dato, senza avere conoscenza del modo in cui esso verr rappresentato dalla View. Se in una lista di persone dobbiamo mostrare un colore diverso a seconda del sesso, blu per i maschietti e rosa per le femminucce, allora il ViewModel si limiter a indicare il sesso del contatto visualizzato. Sar poi responsabilit della View decidere cosa deve essere visualizzato e in che forma.

Una soluzione decisamente elegante e che ci viene incontro in questo contesto è l’utilizzo del DataTrigger.

La via elegante: il Data Trigger

In Xamarin.Forms un trigger permette di definire un’azione al verificarsi di un’evento o al cambio del valore di una propriet . La sua peculiarit ? Possiamo definire tutto in XAML, a livello dichiarativo, senza scrivere una riga di codice. Esistono quattro diverse tipologie di Triggers:

  • Property Trigger: attivato quando la propriet di un controllo viene impostata su un particolare valore;
  • Event Trigger: attivato quando da un controllo viene generato un particolare evento;
  • Multi Trigger: consente l’attivazione del trigger sulla base della valutazione di più condizioni;
  • Data Trigger: consente di verificare la condizione del trigger, su una specifica propriet , utilizzando il binding;

Nello specifico scenario, ovviamente, il DataTrigger è il tipo di trigger che fa al caso nostro. Il codice è decisamente semplice. Dobbiamo aggiungere alla collection Triggers di un controllo Xamarin.Forms, ad esempio BoxView, e definire la propriet del ViewModel da controllare e il valore che quella propriet deve avere per attivare il trigger. Se la condizione si verifica, viene utilizzato il Setter definito nel trigger per impostare la propriet BackgroundColor del BoxView su un nuovo colore, Pink in questo caso:

<BoxView.Triggers>
	<DataTrigger TargetType="BoxView" Binding="{Binding Gender}" Value="{x:Static vm:GenderType.Female}" >
		<Setter Property="BackgroundColor" Value="Pink" />
	</DataTrigger>
</BoxView.Triggers>

 

Questo il codice completo del ListView:

<ListView ItemsSource="{Binding Contacts}" Margin="0,50,0,0">
	<ListView.ItemTemplate>
		<DataTemplate>
			<ViewCell>
				<StackLayout Orientation="Horizontal">
					<BoxView WidthRequest="5" BackgroundColor="Blue">
						<BoxView.Triggers>
							<DataTrigger TargetType="BoxView" Binding="{Binding Gender}" Value="{x:Static vm:GenderType.Female}" >
  								<Setter Property="BackgroundColor" Value="Pink" />
							</DataTrigger>
						</BoxView.Triggers>
					</BoxView>
					<Label Text="{Binding Name}" VerticalOptions="Center" />
				</StackLayout>
			</ViewCell>
		</DataTemplate>
	</ListView.ItemTemplate>
</ListView>

e questo il risultato finale:

Semplice!

Optimizing performance in your Xamarin app

Performance are one of the key features in the app development. If your app is too slow, the users will close it immediately. In this post, you can find some interesting videos from Channel9 about performance optimization of apps builded with Xamarin.

Xamarin.Forms Performance Tips and Tricks

Optimizing App Performance with Xamarin.Forms

Performance Adventures

The Xamarin Show 11: Xamarin Profiler with Nina Vyedin

Additionally, you can check out some tips and tricks links:

Enjoy!

Keep It Simple!

Antoine de Saint-Exupéry wrote in his book The Little Prince the following phrase:

“Perfection is Achieved Not When There Is Nothing More to Add, But When There Is Nothing Left to Take Away”

Thinking about this small sentence, I would like to share with you some small considerations applying it in software development.

Simplicity is the most complex thing {.headline.hover-highlight.entry-title.js_entry-title}

Think about software development. Many developers tend to create complex architectures, adding unnecessary patterns or over engineered code. Why they do that? Because they are trying to set the path for future changes that is gonna happen almost…never!

For example: you choose to abstract a component usage – by using IoC, for example – because, maybe one day, you must be able to use a different component and you don’t wont to change every time your code. Nice and good practice! But, it is really necessary in a iOS app? Maybe yes but, really, how many times you’ll change that component in the app lifetime? Except for really rare case, from zero to one time.

So, in that case, abstraction it’s like to take “a sledgehammer to crack a nut“.

Lets evolve your architecture {.headline.hover-highlight.entry-title.js_entry-title}

When your requirements are really not clear at first, write the most simpler code. If you need to read data from database, try to create a simple interface with direct read. This is not so bad at all. When you need to access to the database from another point or view, change your architecture by refactoring your code to create your data access layer.

The idea is simple: introduce changes in your architecture as late as possibile and only if it is strictly necessary. You can’t predict the future, so don’t do unnecessary things.

Obviously, if your requirements are clear, keep in mind your architecture while developing!

ASP.NET Core Mobile Service with Visual Studio for Mac

With Visual Studio for Mac, a lot of new project templates are now available to macOS developers. For example, you can now create an ASP.NET Core or a .NET Core console project directly on your Mac. Wow! But, in my opinion, one of the most interesting project template is the Connected App. With this template you’ll be able to create a complete solution with a Mobile app (iOS, Android and Windows or Xamarin.Forms) and a Backend app, an ASP.NET Core mobile project that will be hosted in an Azure Mobile Services app.

In this post we’ll see how we can create a Connected App and publish our backend to Azure by using GitHub as source control host. Yes, it is a Continuos Delivery system.

Step 1 | Create a GitHub Repository

First of all, you need to create a new GitHub repository. If you already have a GitHub repository, please go ahead. So, navigate to your GitHub page and on Repository tab click on New. After that, create a README.md file to initialize your repository and, on desktop side, clone the repository by using your git client (like GitHub Desktop).

For a full guide, follow these steps: https://help.github.com/articles/creating-a-new-repository/

Step 2 | Create a Connected App solution

After you have created and cloned the repository, open Visual Studio for Mac and create a new project in the local repository folder by using the Connected App template:

Now we have a complete solution, from frontend, the mobile apps, to backend, the web api app:

By using your git client, commit and push the project on GitHub.

Step 3 | Publish to Azure via GitHub

Finally we are now ready to publish the service to Azure. So, go to the Microsoft Azure portal, log-in into your account and create a new Mobile App.

Set up the Mobile Service with your preferred settings:

To connect our Mobile Service to GitHub, go to Deployment Options and choose GitHub as source.

Then you’ll be requested to authorize access to the GitHub account.

Finally, select the repository and the branch you’d like to use.

And you have done! Now Azure automatically start the deployment process and … BOOM!

Yes! You got the following error:

Command: "D:\home\site\deployments\tools\deploy.cmd"
Handling ASP.NET Core Web Application deployment.
D:\home\site\repository\XConn\Droid\XConn.Droid.csproj(137,3): error MSB4019: The imported project "D:\Program Files (x86)\dotnet\sdk\1.0.0-preview3-004056\Xamarin\Android\Xamarin.Android.CSharp.targets" was not found. Confirm that the path in the <Import> declaration is correct, and that the file exists on disk.
D:\home\site\repository\XConn\iOS\XConn.iOS.csproj(163,3): error MSB4019: The imported project "D:\Program Files (x86)\dotnet\sdk\1.0.0-preview3-004056\Xamarin\iOS\Xamarin.iOS.CSharp.targets" was not found. Confirm that the path in the <Import> declaration is correct, and that the file exists on disk.
Failed exitCode=1, command=dotnet restore "XConn\XConn.sln"
An error has occurred during web site deployment.
\r\nD:\Program Files (x86)\SiteExtensions\Kudu\59.51212.2600\bin\Scripts\starter.cmd "D:\home\site\deployments\tools\deploy.cmd"

Step 4 | Publish with a Custom Deployment script

What happen? Just some background info. The deployment process is governed by Kudu, “the engine behind git/hg deployments, WebJobs, and various other features in Azure Web Sites”. In small words, Kudu scan the repository to find a project to publish. When done, it will generate a deployment script which first step is restoring NuGet packages from the solution.

Ah, the solution! The Connected App solution also include the Xamarin.iOS and Xamarin.Android project. Bingo! The deployment process is trying to solve and build the Xamarin packages on Azure Mobile Service, which is not allowed!

So, what we’ll do is to create a custom deployment script to restore, build and publish only the Mobile Service project. To do that we’ll use a .deployment file (check instruction here):

[config]
command = deploy.cmd

And this is the custom deployment script that you can customize by only replacing the project name:

@if "%SCM_TRACE_LEVEL%" NEQ "4" @echo off

:: ----------------------
:: KUDU Deployment Script
:: Version: 1.0.10
:: ----------------------

:: Prerequisites
:: -------------

:: Verify node.js installed
where node 2>nul >nul
IF %ERRORLEVEL% NEQ 0 (
  echo Missing node.js executable, please install node.js, if already installed make sure it can be reached from current environment.
  goto error
)

:: Setup
:: -----

setlocal enabledelayedexpansion

SET ARTIFACTS=%~dp0%..\artifacts

IF NOT DEFINED DEPLOYMENT_SOURCE (
  SET DEPLOYMENT_SOURCE=%~dp0%.
)

IF NOT DEFINED DEPLOYMENT_TARGET (
  SET DEPLOYMENT_TARGET=%ARTIFACTS%\wwwroot
)

IF NOT DEFINED NEXT_MANIFEST_PATH (
  SET NEXT_MANIFEST_PATH=%ARTIFACTS%\manifest

  IF NOT DEFINED PREVIOUS_MANIFEST_PATH (
    SET PREVIOUS_MANIFEST_PATH=%ARTIFACTS%\manifest
  )
)

IF NOT DEFINED KUDU_SYNC_CMD (
  :: Install kudu sync
  echo Installing Kudu Sync
  call npm install kudusync -g --silent
  IF !ERRORLEVEL! NEQ 0 goto error

  :: Locally just running "kuduSync" would also work
  SET KUDU_SYNC_CMD=%appdata%\npm\kuduSync.cmd
)
IF NOT DEFINED DEPLOYMENT_TEMP (
  SET DEPLOYMENT_TEMP=%temp%\___deployTemp%random%
  SET CLEAN_LOCAL_DEPLOYMENT_TEMP=true
)

IF DEFINED CLEAN_LOCAL_DEPLOYMENT_TEMP (
  IF EXIST "%DEPLOYMENT_TEMP%" rd /s /q "%DEPLOYMENT_TEMP%"
  mkdir "%DEPLOYMENT_TEMP%"
)

IF DEFINED MSBUILD_PATH goto MsbuildPathDefined
SET MSBUILD_PATH=%ProgramFiles(x86)%\MSBuild\14.0\Bin\MSBuild.exe
:MsbuildPathDefined
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:: Deployment
:: ----------

echo Handling ASP.NET Core Web Application deployment.

:: 1. Restore nuget packages
call :ExecuteCmd dotnet restore "XConn\MobileAppService\XConn.MobileAppService.csproj"
IF !ERRORLEVEL! NEQ 0 goto error

:: 2. Build and publish
call :ExecuteCmd dotnet publish "XConn\MobileAppService\XConn.MobileAppService.csproj" --framework netcoreapp1.0 --configuration Release --output "%DEPLOYMENT_TEMP%"
IF !ERRORLEVEL! NEQ 0 goto error

:: 3. KuduSync
call :ExecuteCmd "%KUDU_SYNC_CMD%" -v 50 -f "%DEPLOYMENT_TEMP%" -t "%DEPLOYMENT_TARGET%" -n "%NEXT_MANIFEST_PATH%" -p "%PREVIOUS_MANIFEST_PATH%" -i ".git;.hg;.deployment;deploy.cmd"
IF !ERRORLEVEL! NEQ 0 goto error

::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
goto end

:: Execute command routine that will echo out when error
:ExecuteCmd
setlocal
set _CMD_=%*
call %_CMD_%
if "%ERRORLEVEL%" NEQ "0" echo Failed exitCode=%ERRORLEVEL%, command=%_CMD_%
exit /b %ERRORLEVEL%

:error
endlocal
echo An error has occurred during web site deployment.
call :exitSetErrorLevel
call :exitFromFunction 2>nul

:exitSetErrorLevel
exit /b 1

:exitFromFunction
()

:end
endlocal
echo Finished successfully.

Finally, you can publish the .deployment and deploy.cmd files to the root of the repository. Once done, the deployment process restart and now … the Mobile Service is up and running!

Happy coding!