May 19, 2021

Writing plugins and If conditions

This may be a silly post but it's something bothered me enough to write it down, so I just start with a disclaimer:

if you are using a tool or some code to assist you writing a plugin go for it, this post is not about this.

Few weeks ago I watched a YouTube video about programming, it described the advantages to don't write else conditions, I don't recall the exact remarks but was something like this, so instead of writing:

if (condition == true) {
} else {
}

the author suggested to write something like

if (condition == true) {
}
if (condition == false) {
}

I don't agree by principle, some comments suggested that a switch can also be used, in the example the author probably put some else if statements and one thing I don't like is definitely else if.

Today I wrote a plugin, as usual I copied the wireframe from one that I previously created and I implemented the logic. It was working but the final part of my code was just a long list of closing brackets of several if conditions I had in the code. So I remember the YouTube video I watched and I told myself: Can I rewrite this plugin to avoid a concatenation of if conditions?

Usually my wireframe looks like:

if (context.InputParameters.Contains("Target") && context.InputParameters["Target"] is Entity) {
   Entity entity = context.InputParameters["Target"];
   if (entity.LogicalName == "account) {
      if (context.PostEntityImages.Contains("PostImage") && context.PostEntityImages["PostImage"] is Entity) {
          Entity postImage = (Entity)context.PostEntityImages["PostImage"];
          // rest of the code
      }
   }   
}          
When you start with this kind of style (copied from official documentation or tutorials) it's easy to follow the same structure, you go for the true path, and in the last if condition the main code is executed or else it fails, the majority of the previous if we don't care, because the plugin logic should probably be skipped.
Inside a plugin I usually forgot that I can use return if I want to close the plugin, it doesn't go to an error, just the main scenario should not be executed.

So I rewrote the plugin reversing the conditions, so my code looked like:
if (!context.InputParameters.Contains("Target") || !(context.InputParameters["Target"] is Entity)) { return; }
Entity entity = context.InputParameters["Target"];
if (entity.LogicalName != "account) { return; }
if (!context.PostEntityImages.Contains("PostImage") || !(context.PostEntityImages["PostImage"] is Entity)) { return; }
Entity postImage = (Entity)context.PostEntityImages["PostImage"];
// rest of the code     
One thing I noticed reversing the conditions is that I use often !string.IsNullOrWhiteSpace to check if a value is not empty and continue, inside this plugin I used string.IsNullOrWhiteSpace with a return (meaning I exit if the value is empty), made me curious to know which syntax the author(s) of this method may like.

Just a note, in the code I wrote above I retrieve the Image by name, my friend Daryl LaBar taught me that you can just check the existence and access the first item of the collection, because normally you register a single Image against your step.

This post is not a best practice one or similar, just writing down the thoughts I had in mind today.

May 8, 2021

Microsoft.PowerPlatform.Dataverse.Client and ClientSecret AuthType

.NET Core 3.1 is what I consider a good starting point if you plan to create a new project based on .NET Core, it's LTS (until end of 2022) and if you developed only with .NET Framework before, I usually suggest this version.

I know .NET 5.0 has been released for some months now but for what I am describing here it's not important, if you wish you can use this version.

If you are a developer and in the last years you worked with Dynamics CRM/CDS/Dataverse you probably know this NuGet package:
Microsoft.CrmSdk.XrmTooling.CoreAssembly

It's the package we usually install when we need to connect to Dataverse, it works but requires .NET Framework 4.6.2 or onward. It works also with ClientSecret AuthType, if you have this kind of connection string

AuthType='ClientSecret'; ServiceUri='https://mywonderfulorg.crm.dynamics.com';
ClientId='00000000-0000-0000-0000-000000000000'; ClientSecret='MyWonderfulClientSecret';

or if you are using Username & Password you may have something like this

AuthType='Office365'; Url='https://mywonderfulorg.crm.dynamics.com';
Username='username@mywonderfulorg.onmicrosoft.com'; Password='MyWonderfulPassword';

In your code you can connect with few lines:

CrmServiceClient service = new CrmServiceClient(connectionString);
WhoAmIResponse whoAmIResponse = (WhoAmIResponse)service.Execute(new WhoAmIRequest());
Console.WriteLine($"Connected with UserId: {whoAmIResponse.UserId}");

CrmServiceClient comes from the namespace Microsoft.Xrm.Tooling.Connector.

What if we want to use .NET Core? The NuGet package to use is currently in public preview:
Microsoft.PowerPlatform.Dataverse.Client

You can use this package also with .NET Framework and .NET 5.0 but the main reason is the compatibility with what we call .NET Core (and if you still want to say something like "but with .NET 5.0 we can bla bla bla" fine for me, also with .NET Core is possible to use .NET Framework packages but we would make the executable only compatible with Windows, I never suggested that kind of path but it's a possibility).

This package is not compatible with the Username & Password authentication, as stated inside the description: Note: that only OAuth, Certificate, ClientSecret Authentication types are supported at this time.
Meaning it's also a good time to move away from old forms of authentication.

Assuming you have a connection string with the ClientSecret AuthType how would our code changes? Just a type:

ServiceClient service = new ServiceClient(connectionString);
WhoAmIResponse whoAmIResponse = (WhoAmIResponse)service.Execute(new WhoAmIRequest());
Console.WriteLine($"Connected with UserId: {whoAmIResponse.UserId}");

ServiceClient comes from the namespace Microsoft.PowerPlatform.Dataverse.Client, that is also the name of the package, so make sure you are using it.

Hopefully next time I will remember that is called ServiceClient and not CrmServiceClient, DataverseClient or PowerPlatformClient, types I tried before checking what was inside the package.



March 10, 2021

Power Automate Desktop, opinions of others

Few days after the announcement of Power Automate Desktop for Windows 10 users (official link here) a famous Italian website focused on IT released a brief news about it (link here).

Microsoft is a big name so it is normal that something regarding Windows 10 made the news also inside this site (for example they published also the Microsoft-Bethesda agreement) but I was more interested in the comments.

First some numbers, the article contains 17 comments, I checked the recent news and except an article about Tesla Cybertruck (with 35 comments), the Power Automate Desktop one was the most commented (usually there are between 6 and 10 comments in other news).

This is very good in my opinion, people read the news and after wanted to discuss it, but what they are talking about?

A couple of comments are about the comparison to Mac (Apple Script is mentioned and the fact this is is coming to Windows years later), no surprises here, I also mentioned this in my previous post.

A user asked if can save something to PDF, rename it and after move it to a specific folder, another user promptly replied that is possible, that he is also checking the software and it looks useful.

Another user wrote that he downloaded the software, that is complex (meaning that you can do many things) and reported that maybe for his daily activities is not useful but he would like to check some demos.

Another comment was that in the download page there is the "Download now" option and "Buy" option, this made him confused.

A couple of users (in order to explain to others) compared Power Automate Desktop to IFTTT or to a Macro system.

Last comment was a bit more technical, the software was always intended as Business oriented, Powershell is also available for some automations under Windows.

In the end was good to see how this kind of product is received to a bigger audience, most of the comments were positive and they confirm my initial thought, having Power Automate Desktop included inside Windows 10 can be very beneficial.


March 3, 2021

Power Fx and Power Automate Desktop, my opinion

Microsoft announced a couple of things regarding Power Platform, Power Fx and Power Automate Desktop for Windows 10 users.

I start with Power Fx, you can find a couple of posts here:
Introducing Microsoft Power Fx: the low-code programming language for everyone
What is Microsoft Power Fx?

I am happy the language used in Canvas Apps got an official name (and it will be Open Source too) but I am not surprised, sooner or later (just for Documentation purposes) you need to call this agglomerate of functions in some way, so people can easily check or ask questions about it.

I am also happy that the code behind a Canvas App can be easily stored inside a source control system but let's be honest, nobody in a clear state of mind would be happy to edit that kind of YAML files directly :)

For how long we will continue to talk about low-code, citizen developers and stuff like that? When I was younger I developed applications with Visual Basic 6, I am sure that people developing in C++ thought about Visual Basic like it's a toy or something similar, the reality is that who used Visual Basic was probably a developer with less knowledge than the average C++ developer, nothing to be ashamed for, because there is a difference if I need to create a Windows driver for a PC component or a Windows Forms application to manage my customers.

As much as I appreciate the games developed by Scott Durow for Canvas Apps, using just a specific option (like a Canvas App or a writing a plugin) because it's technically possible should be (in my opinion) avoided. Like writing a 1000 lines of code plugin instead of 3 blocks inside a flow, or creating the biggest flow on earth just to avoid a 10 lines of code plugin. I think less of who write code in Canvas Apps? Definitely not, I call them "citizen developers"? Definitely not, if you know how to develop good for you, if you found a tool that encourage you to write better and lesser code good for you. For me Power Fx is not a low-code language, it's just a code language, like C#, JavaScript, VBA Macros, etc etc. Why I say this? because I can be proficient in one of the most common code languages, but I am sure that there are plenty of developers (maybe proficient in Assembler) developing more complicated stuff than I do. But the moment we write some code we are all developers, that's matter.

Moving to a more interesting topic, the new release of Power Automate Desktop for Windows 10 users is an AMAZING news. Announcement post:
Automate tasks with Power Automate Desktop for Windows 10—no additional cost

This is a game changer for Windows, if you are familiar with Mac, it is comparable to what Automator does. I quickly downloaded the application (link is https://aka.ms/GetStarted-PAD) and it's really something users should try.

Check this screenshot:


These are the actions related to FTP, imagine that your security camera saves the files in a specific FTP site and you want to copy automatically that files to a local folder (maybe synced with OneDrive), no manual steps, you can just create the automation and launch it.
Having a tool like this included in Windows will make users more familiar with the technology itself and the possibilities it offers, this means that when a user will need to automate some tasks in a work environment, already has the experience to do this kind of tasks.

Next time I need to create a repetitive task, I will definitely check if I can do it using Power Automate Desktop first.