Archivi tag: code

SOLID principles by examples: single responsability

This blog post will explain with simple examples the Singe Responsabily Principle of SOLID agiles principles to better understand how we can improve our daily coding activites. In future post I’ll cover the other four priciples.

The Definition

A class should have only one reason to change.

Defined by Robert C. Martin in his book Agile Software Development, Principles, Patterns, and Practices it is the first of the five SOLID agile principles. What it states is very simple, however achieving that simplicity is not so obvious.

Continua a leggere SOLID principles by examples: single responsability

UWP Prism Unit Test

I’m sure we all hear about unit testing, test driven development and so on. These practices are useful and provide a long list of benefit like writing low-coupled and mantainable code to name a few.

We want to write unit test for our UWP Prism application and we’d like, for example, to put our ViewModels under tests to make sure the logic they implement is correct. Unit testing is possible only if we can get rid of all the dependencies in our class under test because we want to run our test every time we want (for exemple when the service library our teammate is writing is not yet finished) and as fast as we can.

Continua a leggere UWP Prism Unit Test

Prism UWP for beginners: events

In this post we explore another major component of Prism: the EventAggregator.

The Prism library provides an event mechanism to communicate between loosely coupled components in the application. Using .NET Framework events is the most straightforward approach for communication between components if loose coupling is not a requirement. Events in the .NET Framework implement the Publish-Subscribe pattern, but to subscribe to an object, you need a direct reference to that object, which, in composite applications, typically resides in another module. This is a tightly coupled design.

The EventAggregator provides a mechanism to matain the application loosely-coupled. It provides a multicast publish/subscribe funcionality (there can me multiple publishers of the same event with multiple subscribers).

image

We can obtain a reference to the EventAggregator using the container, for example we can write this code in the OnInitializeAsyunc method of the App class that is our bootstrapper.

protected override Task OnInitializeAsync(IActivatedEventArgs args)
         {
Container.RegisterInstance<IEventAggregator>(new EventAggregator());
return base.OnInitializeAsync(args);
         }

Events

Before we start publishing and subscribing to events we need to declare them. Events are simple classes that inherit from PubSubEvent<T> in the Prism.Event namespace. T is the type of the payload of our message. We declare our simple event like this:


class SimpleEvent : PubSubEvent&lt;string&gt;
&nbsp;&nbsp;&nbsp;&nbsp; {

&nbsp;&nbsp;&nbsp; }

In this case we defined an event which payload is a string.

Publisher

Now let’s make an example of a viewmodel that publishes an event of that type.


class PublisherViewModel {

	public DelegateCommand SendMessage { get; private set; }

        private readonly IEventAggregator _eventAggregator;

	public PublisherViewModel(IEventAggregator eventAggregator)
        {
            if (eventAggregator == null)
            {
                throw new ArgumentNullException(nameof(eventAggregator));
            }

            _eventAggregator = eventAggregator;

            SendMessage = new DelegateCommand(() =&gt;
            {
                _eventAggregator.GetEvent&lt;SimpleEvent&gt;().Publish(DateTime.Now.ToString());
            });
        }
}

In the constrctor we specified a parameter to hold a reference to an instance of IEventAggregator. The container will do the heavylifting and inject the parameter every time we need an instance of PublisherViewModel. We defined a DelegateCommand that publishes a message using the EventAggregator: that message will have the currente date and time in string format.

Subscriber

Now we can define a subscriver view-model that listens to this type of events.

 

class SubscriberViewModel
{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; private readonly IEventAggregator _eventAggregator;	

	public SubscriberViewModel(IEventAggregator eventAggregator)
	{
		if (eventAggregator == null)
		{
			throw new ArgumentNullException(nameof(eventAggregator));
		}
		_eventAggregator = eventAggregator;

		_eventAggregator.GetEvent&lt;SimpleEvent&gt;().Subscribe((dateDesc) =&gt;
{
//Do something with datedesc.
});
	}
} 

With the

_eventAggregator.GetEvent<SimpleEvent>().Subscribe(...)

line of code we set our SubscriberViewModel class to listen to events of type SimpleEvent and we can specify what we would like to do when the class is notified.

And that’s it! Managing messages between components is very easy thanks to Prism.

TL;DR

In this post we learned how components can communicate in a Prism app in a decoupled fashion. The EventAggregator is the main actor of this funcionality and it acts as a post office to deliver messages from publishers to subscribers.

 

Prism UWP posts

Only the code tells the truth

Treat your code like any other composition, such as a poem, an essay, a public
blog, or an important email. Craft what you express carefully, so that it
does what it should and communicates as directly as possible what it is doing;
so that it still communicates your intention when you are no longer around.
Remember that useful code is used much longer than ever intended. Maintenance
programmers will thank you. And, if you are a maintenance programmer
and the code you are working on does not tell the truth easily, apply the
aforementioned guidelines in a proactive manner. Establish some sanity in the
code, and keep your own sanity.

– Peter Sommerlad (from “97 things every programmer should know”)

Integrate Azure Cognitive Services in UWP app

Azure Cognitive Services are an amazing tool than enables developers to augment users’ experience using the power of machine-based intelligence. The API set is powerful and provides lots of features that are organized in categories: vision, speech, language, knowledge, search, and labs.image

In this post we learn how to leverage the Emotion API to get our user mood and set a background of our app accordingly.

Get API key

To get starded we need to get an API key to be able to access the Cognitive Services. So, let’s go to this address (https://azure.microsoft.com/en-us/try/cognitive-services/?api=emotion-api) and click on the Create button next to Emotion API.

image

After that the website will ask to accept the trial term of services and we accept:

image

After the login we get access to our keys:

image

Now we’re done with Azure web site and we can start coding.

Coding

We fire up Visual Studio and create a new UWP project.

image

To achieve our goal (get our user mood and change the background) where’re going to develop a simple UI where the user press a button, we take a picture of him/her, send that picture to Azure, and based on the result load a background image.

Before we write code we need to setup our application capabilities in the manifest and download some NuGet packages. We double click on the Package.appxmanifest file in Solution Explorer and Visual Studio, go to the Capabilities tab and check the webcam and microphone boxes.

image

Then we download the Microsoft.ProjectOxford.Emotion NuGet package that contains some helper classes to deal with the Azure Cognitive Services. In the Solution Explorer we right click and select Manage NuGet Packages. In the search box we type “Microsoft.ProjectOxford.Emotion”. We download the package.

image

With the following XAML we draw a simple UI with a Button to trigger the camera.

<Page x:Class="IC6.EmotionAPI.MainPage"       xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"       xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"       xmlns:local="using:IC6.EmotionAPI"       xmlns:d="http://schemas.microsoft.com/expression/blend/2008"       xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"       mc:Ignorable="d">

    <Grid Name="myGrid">
        <StackPanel>
            <Button Click="Button_Click">Take a camera picture</Button>

        </StackPanel>
    </Grid>
</Page>

At the handler of the click event we write


  private async void Button_Click(object sender, RoutedEventArgs e)
        {
            try
            {

                using (var stream = new InMemoryRandomAccessStream())
                {
                    await _mediaCapture.CapturePhotoToStreamAsync(ImageEncodingProperties.CreateJpeg(), stream);

                    stream.Seek(0);

                    var emotion = await MakeRequest(stream.AsStream());

                    if (emotion == null)
                    {
                        await new MessageDialog("Emotions non detected.").ShowAsync();

                        return;
                    }

                    var imgBrush = new ImageBrush();

                    if (emotion.Scores.Sadness &amp;amp;amp;gt; emotion.Scores.a)
                    {
                        imgBrush.ImageSource = new BitmapImage(new Uri(@"ms-appx://IC6.EmotionAPI/Assets/sad.jpg"));
                    }
                    else
                    {
                        imgBrush.ImageSource = new BitmapImage(new Uri(@"ms-appx://IC6.EmotionAPI/Assets/happy.jpg"));
                    }

                    myGrid.Background = imgBrush;

                }

            }
            catch (Exception ex)
            {
                await new MessageDialog(ex.Message).ShowAsync();
            }
        }

In this method we’re leverging the power of the MediaCapture class that provides functionality for capturing photos, audio, and videos from a capture device, such as a webcam. The InitializeAsync method, which initializes the MediaCapture object, must be called before we can start previewing or capturing from the device.

In our exercise we’re going to put the MediaCapture initialization in the OnNavigatedTo method:

        protected async override void OnNavigatedTo(NavigationEventArgs e)
        {
            base.OnNavigatedTo(e);

            if (_mediaCapture == null)
            {
                await InitializeCameraAsync();
            }

        }

InitializeAsync is a helper method we write to search for a camera and try to initialize it if we find one.

  private async Task InitializeCameraAsync()
        {

            // Attempt to get the front camera if one is available, but use any camera device if not
            var cameraDevice = await FindCameraDeviceByPanelAsync(Windows.Devices.Enumeration.Panel.Front);

            if (cameraDevice == null)
            {
                Debug.WriteLine("No camera device found!");
                return;
            }

            // Create MediaCapture and its settings
            _mediaCapture = new MediaCapture();

            var settings = new MediaCaptureInitializationSettings { VideoDeviceId = cameraDevice.Id };

            // Initialize MediaCapture
            try
            {
                await _mediaCapture.InitializeAsync(settings);
            }
            catch (UnauthorizedAccessException)
            {
                Debug.WriteLine("The app was denied access to the camera");
            }
        }

        ///
<summary>
        /// Attempts to find and return a device mounted on the panel specified, and on failure to find one it will return the first device listed
        /// </summary>

        /// <param name="desiredPanel">The desired panel on which the returned device should be mounted, if available</param>
        /// <returns></returns>
        private static async Task<DeviceInformation> FindCameraDeviceByPanelAsync(Windows.Devices.Enumeration.Panel desiredPanel)
        {
            // Get available devices for capturing pictures
            var allVideoDevices = await DeviceInformation.FindAllAsync(DeviceClass.VideoCapture);

            // Get the desired camera by panel
            DeviceInformation desiredDevice = allVideoDevices.FirstOrDefault(x => x.EnclosureLocation != null && x.EnclosureLocation.Panel == desiredPanel);

            // If there is no device mounted on the desired panel, return the first device found
            return desiredDevice ?? allVideoDevices.FirstOrDefault();
        }

Let’s focus on the MakeRequest method we called in the click event handler because here we make use of the Project Oxford library to detect emotions.

private async Task<Emotion> MakeRequest(Stream stream)
        {
            var apiClient = new Microsoft.ProjectOxford.Emotion.EmotionServiceClient("f1b67ad2720944018881b6f8761dff9a");
            var results = await apiClient.RecognizeAsync(stream);

            if (results == null) return null;

            return results.FirstOrDefault();
        }

We need to create an instance of the Microsoft.ProjectOxford.Emotion.EmotionServiceClient class. In the constructor we pass the key obtained from the Azure portal at the beginning of this post. Then, we call the RecognizeAsync method. Here we’re using the overload with the Stream parameter because we have our picture saved in memory. There is also an overload that accepts a URL string. With this call the Azure platform is now doing its magic and soon it’ll deliver the result. The RecognizeAsync returns an array of Emotion. An Emotion is made by a Rectagle reference and a Score reference. The Rectagle instance tells us the coorindates of the face detected while the Score instance tells us the confidence of every mood that Azure can detect: sadness, neutral, happiness, surprise, fear, and anger. Based on this data we can make “ifs” to do some funny things like changing the background of our main window.

TL; DR

In this post we learned how to detect the current mood of our user. We achieved that by using our front camera to take a picture and then make a call to Azure Emotion API to guess if our user is happy or not. We had to set the app manifest to inform the OS that we need to use the Webcam to ask the user for the privacy settings.

If you want to learn more about the MediaCapture class, visit MSDN (https://docs.microsoft.com/en-us/uwp/api/windows.media.capture.mediacapture) and the Azure Cognitive Services (https://azure.microsoft.com/en-us/services/cognitive-services/) website. The source code of the app developed in this post is available on my GitHub (https://github.com/phenixita/IC6.EmotionAPI).

Social

If you have questions you can use the comment section below or you can find me on Twitter! If you liked this post, share!

Fare giusto VS fare in fretta

Sappiamo tutti come ci si sente.

Inizia un progetto nuovo.

La possibilità di riscattarsi dalle schifezze del passato profuma di carta stampata. Vuoi dare il meglio e questa è la volta buona. I compromessi saranno pochi e ben calibrati.

Il mondo reale è inesorabile e pretende che tu consegni in quella fatidica data. Al cliente non interessa se hai usato MVC, ASP, SQL, Ruby, Perl o un rito voodoo. Basta che vada e che costi poco e sia facile da usare. Basta che la sua azienda possa fatturare e che nella sua carta di credito ci sia sempre disponibilità per fare il pieno alla sua Porsche Cayenne nera con cerchi di dimensioni improbabili e finestrini oscurati.

Ti senti un po’ sotto pressione e nella testa i neuroni che tifano per “fare giusto” e quelli che tifano per “fare in fretta” cominciano a scontrarsi. Allora qualche pezzo di codice ti scappa ma ti prometti che una volta consegnata una prima versione base tornerai indietro e sistemerai quel taccone e farai le cose fatte bene.

Quella promessa che ti sei appena fatto si fa chiamare debito tecnico intenzionale. Come i debiti finanziari, anche quelli tecnici hanno gli interessi. Adesso l’hai scampata andando veloce; loro però cammineranno inesorabili e, quando non avrai più il fiato per andare veloce, ti raggiungeranno e ti presenteranno il conto.
E, a quel punto…

Il COBOL degli anni 2020

Visual Basic 6 morirà? Non a breve, per lo meno. Kale Peterson di Visual Studio Magazine lo definisce addirittura il COBOL degli anni 2020.

VB6

Quando uscì, Windows 7 sembrava l’ultimo sistema operativo su cui Microsoft avrebbe speso risorse per fare funzionare il runtime di VB6. Invece tale dichiarazione viene costantemente aggiornata e gli sforzi sono tutt’ora attivi anche per Windows 10.

Come mai? La mia esperienza mi porta a pensare che il linguaggio sia ancora supportato perché molte aziende si basano su applicazioni VB6 per processi mission critical. La maggior parte di chi programmava in VB6 non è stata in grado di fare il salto tecnologico richiesto da .NET, negli anni dove con qualche form e un database (Access!) si facevano decine di milioni di Lire/decine di migliaia di Euro. Aggravava la situazione il fatto che i tool di migrazione messi a disposizione da MS non fossero così evoluti e richiedessero molti interventi manuali (strumenti ritirati poi con Visual Studio 2010). Così i consulenti software hanno proseguito col fornire soluzioni, ricche di personalizzazioni e quindi costose. Rimpiazzare la stessa applicazione riscritta con altre tecnologie non è facilmente giustificabile da parte di un’azienda di consulenza che si trova a dover rispondere a queste domande del potenziale cliente:

  • Perché mi devo ricomprare il programma che fa le stesse cose? E quello nuovo crea anche più problemi perché meno collaudato?
  • Perché devo aggiornare quando quello che ho funziona ancora?

Pensando ad alcune risposte efficaci, si potrebbe spiegare al cliente che le tecnologie di sviluppo più recenti permettono di ottenere risultati con costi minori o più velocemente, che rendono più facili gli sviluppi su piattaforme web o mobile. Oltre al fatto che i programmatori di nuova generazione che seguiranno i progetti di tale cliente crescono a pane e Javascript, .Net, HTML; Visual Basic l’hanno sentito nominare solo per motivi storici.

Microsoft tutto ciò lo sa, lo dimostra mantenendo vivo VB6 e quindi tenendosi stretta la sua clientela.

Fare meno schifo ogni anno

Sappiamo tutti noi tecnici come ci si sente a uscire dalla propria zona di comfort e imparare linguaggi o framework nuovi: possiamo quindi capire chi non è riuscito a stare al passo coi tempi. Cala la produttività e il peso delle scadenze diventa improvvisamente maggiore. Inoltre, spiegare al proprio titolare che determinate evoluzioni sono necessarie è difficile se non è tecnologicamente informato.

Se vogliamo chiamarci programmatori di professione, però, dobbiamo trovare il modo per rimanere costantemente aggiornati fare costante pratica ed esercitarci liberamente. Non pensate che, come professionisti, dovremmo sentirci obbligati a farlo? A essere quest’anno meno schifosi dell’anno scorso?
Che ciò avvenga per motivi puramente egoistici, per mantenere vivo il nostro entusiasmo, per farci assumere dall’azienda dei sogni, per realizzare l’app del momento, per sapere cosa succede “là fuori” e come gli altri fanno le cose.
Purché avvenga.

Invece di…

Un collega ha comprato qualche settimana fa SQL Server 2014 Unleashed. È uno dei soliti libro-mattone che potresti usare come fermaporte nelle giornate più ventose. Lo sfogliamo casualmente durante le pause caffè o altre occasioni in cui si stacca dal monitor per prendere fiato. Così mi sono imbattuto nel capitolo dei trigger, in particolare nella sezione degli instead of trigger.

Scopro un mondo parecchio interessante, dei trigger che scattano prima delle effettive operazioni sui dati: a differenza dei trigger tradizionali che scattano ad operazioni eseguite (chiamati trigger AFTER). Nel dettaglio:

  1. Viene recepito un comando DML;
  2. Scatta trigger INSTEAD OF;
  3. Scattano controlli CHECK;
  4. Scatta trigger AFTER.

Esempio:

CREATE TRIGGER dbo.TI_PERSONE_CONTROLLI ON dbo.PERSONE INSTEAD OF INSERT

In un primo momento non ne trovo un’applicazione che potrebbe fare al caso nostro e archivio la questione.

Verso sera capita che abbiamo problemi di spazio su disco presso un cliente. Delle verifiche ci portano a scoprire che una tabella di log è esageratamente grande e popolata erroneamente da un bug di un programma di scambio dati. Il bug era di semplice risoluzione ma per vari motivi era impossibile sostituire il programma nel server. Amari estremi, estremi rimedi:

TRUNCATE TABLE LOG;
CREATE TRIGGER dbo.TI_LOG_ANNULLA_INSERT ON dbo.LOG INSTEAD OF INSERT
AS
BEGIN
	PRINT ''
END;

Il giorno successivo abbiamo sostituito il programma di scambio dati e distrutto il trigger instead of.yes

Riferimenti

MSDN https://msdn.microsoft.com/en-us/library/ms189799.aspx