Monday, January 28, 2013

Passing .Net objects as arguements to PowerShell

In the previous posts about PowerShell to .Net integration, the samples were simply invoking PowerShell scripts from .Net code. In the first post, the sample don't have any parameter at all. It just executed a get-alias command from .Net code. The second which I wrote in relation with DSL, passes the arguments as parameters to a dynamic block which uses '&' for script block execution. The below code snippet is just for  a reference regarding dynamic script block execution.


         private  static  void  RunPowerShellScriptDynamicallyWithParameter(int  inputNumber)
         {
             PowerShell  ps = PowerShell .Create();
             //The format needed for PS to execute dynamic scipr block is 
             //&{param ($paramsAsCommaSeparated);statements;} inputParameters as string 
             string  script = "&{param ($number);if (($number % 2)-eq 0)'}} " +inputNumber.ToString();
             ps.AddScript(script);
             ps.AddParameter("number" , inputNumber);
             Collection <PSObject > result = ps.Invoke();
             //Process logic for resultant PSObjects. 
         }
 


C#/VB.Net objects to PowerShell

There was a small limitation that we can append only string variables / primary datatypes as it uses string concatenation for passing the arguments.To achieve actual object parameter passing in a simple manner you need to define the parameters at the beginning of the script block you want to execute. Then from the .Net code add those parameters.Here is a small code block which validates an .Net FixedDeposit object in powershell code.

         FixedDeposit  fdAccount = new  FixedDeposit () { Customer = new  Customer  { Name = "George" , Age = 70 }, Interest = 9.0 };
         private  void  RunPowerShellScriptWithParameter()
         {
             PowerShell  ps = PowerShell .Create();
             string  script = "param($fd); if ($fd.Customer.Age -ge 60) {$fd.Interest=$fd.Interest+.5}" ;
             ps.AddScript(script);
             ps.AddParameter("fd" , fdAccount);
             Collection <PSObject > result = ps.Invoke();
             //Inspect the fdAccount object for changes 
         }
 

In India all the banks give additional .5 interest to senior citisons (above 60) for their fixed deposits. If this rule comes via a script it can be modified at any time.PowerShell scripts can be also applied to the UI elements ie we can modify / control the .Net UI elements from PowerShell

Monday, January 14, 2013

Unsafe VB.Net programmers

“In computer science, type safety is the extent to which a programming language discourages or prevents type errorswiki

What is type safety in programming

We need to know how the types are being stored in the memory to understand it clearly. Type safety helps the language/runtime to allocate memory properly to the types so that there will be no data loss. If the language is type safe, it should not allow to store string values in an integer variable.

Problem with unsafe code

See the below code which is called not type safe.
int iVar = 256;
byte bVar = (byte)iVar; //value will be 0 as max value can be stored in byte is 255
Console.WriteLine(bVar);



The reason is during the execution the memory allocated to byte variable named bVar is 8bits which can store maximum of 255 (1111 1111).When a value which is greater than 255 comes, it became 0 .Actually it is not zero ( 0 ), it is 1 0000 0000.But only the right 8 bits are considered as the variable type is byte. Simply speaking this can introduce unexpected behavior into our program. VB.Net is such a language where our types are not safe.

Type safety and performance in VB.Net

As I told in the above paragraph, VB.Net allows us to write code which is not type safe. Lets see a code snippet to understand the issue.

Private Function GetValue()
    Return "1"
End Function
Private Function GetCharValue()
    Return "2"c
End Function
Private Sub Unsafe()
    Dim temporaryValue = GetValue() + GetCharValue()
    Dim finalValue = temporaryValue + 2
    Console.WriteLine(finalValue)
End Sub



Don’t confused about the compilation aspects of this program. It will compile and the result is 14. The temporaryValue will hold “12” in the form of string type and finalValue will be calculated to 14 which is result of numeric addition of 12 and 2. Can the string be added to integer in the mathematical way? Is there any magic of type conversion happens?

Yes there is a magic conversion code being injected by the compiler. If you want to see that magic code just use the Reflector which decompiles the assembly into source code.The code you can see in reflector is as follows

private void Unsafe()
{
    Console.WriteLine(RuntimeHelpers.GetObjectValue(Operators.AddObject(Operators.AddObject(this.GetValue(), this.GetCharValue()), 2)));
}



The magic is performed by Operators.AddObject() method. Is this comes in free? certainly not.It has its own performance implications. If you want to see the performance implications, navigate to the source code of Operators.AddObject method using reflector.

Also just think about a situation where the GetValue function returning a string which cannot be converted to number. It will end up in runtime exception. This could have avoided if the function is type safe. ie if function specifies the return type.

How to code VB.Net as type safe

‘ Option Strict On ‘.

This is the solution to all the type safety issues in VB.Net. You can enable this at any level in your source code. File level, project level etc…Better enable option strict at the Visual Studio IDE level itself. There are some more options available along with this which help you to raise compile time errors on ‘function with no return’, ‘use of unassigned variable’ etc…Better turn everything on.

If you are working on large legacy VB.Net codebase it would be difficult to turn the option strict on immediately. But gradually you can achieve that. My current project is a good example for such a project. Hundreds of VB projects which are not type safe. Only possibility is to code new projects in type safe manner. Even though the programmers know that there are possibilities to ensure the type safety in VB.net, some of them are still like to code without option strict on.

It is the programmers who are  type unsafe than the language.

Further reading
http://www.techrepublic.com/blog/smbit/visual-studio-compiler-options-part-2-option-strict/331

Monday, January 7, 2013

DSL Demo : First C# application which uses PowerShell as DSL

As I promised in my previous post, this post is dedicated to fully cover a practical application of DSL by combining 2 of my earlier posts.

http://joymonscode.blogspot.in/2013/01/what-is-domain-specific-language-dsl-in.html
http://joymonscode.blogspot.in/2012/12/running-powershell-script-from-c-vbnet.html

The idea was to give a kick start sample for C# developers into the world of DSL. But before going into the details I would like to add couple of theory titles.

How to select the DSL (Domain Specific Language)

This is a big question before you select the implementation method of DSL. According to Martin Fowler there are 2 categories of DSL. External and Internal DSL.

Internal DSL means adjusting our existing programming language practice to look more like business friendly. ie using plain English constructs to express the business cases. Linq is a best example for that. Also people are using fluent api for achieving internal DSLs. But here there is a considerable limitation. It is little difficult to add support for runtime changes. You can create the framework as a DSL and the tracks ie other developers can use that to achieve their tasks.

External DSL employees same programming language or different language altogether along with its own execution mechanism to run DSL program. SQL is a good example for that. We write C# code and for communicating with DB we need to write entirely different program called SQL queries. The execution engine and the model of SQL execution itself different from C#.

According to me if you are planning to select a DSL to conquer the constant requirements change better go for external DSL. This allows the end users, ability to change the program or behavior at run time. There is another psychological factor. If we ask your users write in C# or any other main stream programming language, they will protest first. But if you ask them to write in javascript or PowerShell they will be OK.This is because according to the end users, the responsibility of writing main stream code always lies with programmers. Can't believe? 

This is proved last week in our office.We have an installation system which expects so many parameters to configure the application such as DB name, IIS application pool name etc...Earlier this has to be entered by the installation guy (QA people in case of testing) at the beginning of an .vbs file.That same vb script file contains the processing logic after the initial declaration section. They usually complain about this process of giving values in .vbs file. According to them its complicated. Now the process changed little bit. We leveraged MS Excel to enter parameter values and wrote vbs to read the values from there. They became very happy. The complication is washed out by introduction of excel. But did we do anything? Yes we removed a mental roadblock of modifying a program file by QA and other installation people. Still they need to enter DB name, application pool name etc...But at a different place.Now they are happy with the installation procedure.

Another thing to remember is, never go for creating your own parser or lexers to execute that external DSL. Of course if you have research time and lavish time you can go.But as an Architect / Technologist the best way is to leverage an existing well proven mechanism to achieve execution of DSL.

In the book "Wings of fire", former Indian president Dr. A.P.J Abdul Kalam is clearly defining the 'difference between science and technology'. According to him, if we are doing experiments to create something really new and we are not sure whether we can produce positive result, it is called as science. In the other hand, if we are doing something with limited resource and we must produce the positive output in time, its called technology.A scientist can go up to any limit to experiment what he wants. But technologist mostly works in constraints, so he needs to be aware of all the available proven options and use those wisely to achieve the goal.

Creating a new DSL and writing its parser and related things is a science. But leveraging the power of PowerShell, Javascript or any other language which can be embedded in our program to achieve the DSL execution is technology. Now you might have understood why the heading says PowerShell as DSL.

C# Salary calculation using PowerShell as DSL

In the previous post I had told about a salary calculation scenario where we can apply DSL to solve the requirement change issue. Basically requirement change is the nature of software engineering rather than  issue. I am not good in explaining theories so I managed to create a C# program which uses PowerShell to accomplish the salary calculation based on dynamic logic written in PowerShell.

Why PowerShell

There is no special interest on PowerShell. You can select any scripting language such as Javascript, Lua etc..Only constraint is the scripting language should support embedding into C# application or there should be some methods to execute the script from C# and communicate back and forth.
The reasons for selecting PowerShell are
  • Its becoming more and more popular like .bat file
  • Easy to write programs using the pipline support.
  • Recently I took a PowerShell hands on training session to a selected audience in our company :)

About the sample

Few words about the embedded sample. Its a simple program to demonstrate how to visualize the working of DSL. This is because most of the C# / VB.Net programmers might have heard about DSL but didn't experienced. It uses simple PowerShell invocation method from C#. In the formula textbox you can enter any PowerShell script snippet which returns a double value. The values for Basic, HRA & DA are available to the PowerShell context as variables $basic, $hra & $da respectively. Try changing the PowerShell code to calculate total salary by considering a 5% basic as metro allowance.
Happy coding...