Wednesday, January 25, 2017

Dynamic methods in C# using CodeDom

In my previous article, we discussed how we can create a dynamic class using CodeDom namespace. Now we will discuss how we can add methods to these classes. For this we will be use the same code as in our previous discussion.
For adding method to the class, we will use CodeMemberMethod class, which provides different properties, to define methods. For our sample we will create a dynamic method which will take two input parameters, calculate their sum and return the sum. Let's with basic method signatures. So our code will look like the following: 
  1. CodeTypeReference methodReturnType = new CodeTypeReference(typeof(System.Int32)); 
  2. CodeMemberMethod myMethod = new CodeMemberMethod();  
  3.   
  4.  // Generate Method signatures.  
  5.  myMethod.Name = "MySum";  
  6.  myMethod.ReturnType = methodReturnType;  
  7.  myMethod.Attributes = MemberAttributes.Public;  
We use of the CodeTypeReference class to specify the return type of our method. To add parameters for this method, we will use the CodeParameterDeclarationExpression class. So our code will look like the following: 
  1. // Initialize for Method parameters  
  2. CodeParameterDeclarationExpression methodPrm1 = new CodeParameterDeclarationExpression(typeof(Int32), "X");  
  3. CodeParameterDeclarationExpression methodPrm2 = new CodeParameterDeclarationExpression(typeof(Int32), "Y");  
  4. myMethod.Parameters.AddRange(new CodeParameterDeclarationExpression[] { methodPrm1, methodPrm2 });  
Next, to specify the method definition we use the CodeSnippetExpression class. Our method will simply the sum of our input parameters. So we will generate an expression to perform the sum of the numbers and add it to the method. So our code will change to the following: 
  1. // Generate method definition  
  2. CodeSnippetExpression codeSnippet = new CodeSnippetExpression("return X + Y");  
  3.   
  4. // Add method definition to method  
  5. myMethod.Statements.Add(codeSnippet);  
Finally we add the method to our class definition using following code: 
  1. // Add method to the class.  
  2. cls.Members.Add(myMethod);  
So our complete code will look like the following: 
  1.  CodeNamespace nameSpace = new CodeNamespace("sampleNameSpace");  
  2.   
  3.  nameSpace.Imports.Add(new CodeNamespaceImport("System"));  
  4.  nameSpace.Imports.Add(new CodeNamespaceImport("System.Linq"));  
  5.  nameSpace.Imports.Add(new CodeNamespaceImport("System.Text"));  
  6.   
  7.  CodeTypeDeclaration cls = new CodeTypeDeclaration();  
  8.  cls.Name = "SampleClass";  
  9.  cls.IsClass = true;  
  10.  cls.Attributes = MemberAttributes.Public;  
  11.  nameSpace.Types.Add(cls);  
  12.   
  13.  // Initialize for Method Return type  
  14.  CodeTypeReference methodReturnType = new CodeTypeReference(typeof(System.Int32));  
  15.  CodeMemberMethod myMethod = new CodeMemberMethod();  
  16.   
  17.  // Generate Method signatures.  
  18.  myMethod.Name = "MySum";  
  19.  myMethod.ReturnType = methodReturnType;  
  20.  myMethod.Attributes = MemberAttributes.Public | MemberAttributes.Final;  
  21.   
  22.  // Initialize for Method parameters  
  23.  CodeParameterDeclarationExpression methodPrm1 = new CodeParameterDeclarationExpression(typeof(Int32), "X");  
  24.  CodeParameterDeclarationExpression methodPrm2 = new CodeParameterDeclarationExpression(typeof(Int32), "Y");  
  25.  myMethod.Parameters.AddRange(new CodeParameterDeclarationExpression[] { methodPrm1, methodPrm2 });  
  26.   
  27.  // Generate method definition  
  28.  CodeSnippetExpression codeSnippet = new  CodeSnippetExpression("return X + Y");  
  29.   
  30. // Add method definition to method  
  31.  myMethod.Statements.Add(codeSnippet);  
  32.   
  33.  // Add method to the class.  
  34.  cls.Members.Add(myMethod);  
  35.   
  36.  CodeCompileUnit compileUnit = new CodeCompileUnit();  
  37.  compileUnit.Namespaces.Add(nameSpace);  
  38.  CSharpCodeProvider csharpcodeprovider = new CSharpCodeProvider();  
  39.   
  40.  CSharpCodeProvider provider = new CSharpCodeProvider();  
  41.   
  42.  using (StreamWriter sw = new StreamWriter(@"C:\TestFile.cs"false))  
  43.  {  
  44.      IndentedTextWriter tw = new IndentedTextWriter(sw, "    ");  
  45.      provider.GenerateCodeFromCompileUnit(compileUnit, tw, new CodeGeneratorOptions());  
  46.      tw.Close();  
  47.  }  
Run the application and see the code getting generated: 
  1. //------------------------------------------------------------------------------  
  2. // <auto-generated>  
  3. //     This code was generated by a tool.  
  4. //     Runtime Version:4.0.30319.42000  
  5. //  
  6. //     Changes to this file may cause incorrect behavior and will be lost if  
  7. //     the code is regenerated.  
  8. // </auto-generated>  
  9. //------------------------------------------------------------------------------  
  10.   
  11. namespace sampleNameSpace {  
  12.     using System;  
  13.     using System.Linq;  
  14.     using System.Text;  
  15.       
  16.       
  17.     public class SampleClass {  
  18.           
  19.         public int MySum(int X, int Y) {  
  20.             return X + Y;  
  21.         }  
  22.     }  
  23. }  
So this was about how we can generate the dynamic class and add methods to it. Hope you enjoyed reading it. Happy coding...!!!

Sunday, January 8, 2017

C# 7 features - Local functions


A preview of C# 7.0 has been introduced with the preview release of Visual Studio 15. This should not be confused with Visual studio 2015, as it is separate.

In order to install visual studio 15, you will have to download the setup from the link here - https://blogs.msdn.microsoft.com/vcblog/2016/10/05/visual-studio-15-preview-5-now-available/ and install the web and desktop development tools.

So we will start with the first feature which is the use of Local functions. Normally we create private sub-functions for code refactoring. However, these functions are exposed to other methods in the class, even though they are not required to use. But in C# 7, we can have functions within the functions. Yes, we can create a function within another function.

For example, following code is valid in C# 7.0:

        static void Main(string[] args)
        {
            var d = GetSalary();
        }
        public static Int32 GetSalary()
        {
            var s = GetSum(10, 6) * 2;

            return s;

            Int32 GetSum(Int32 a, Int32 b)
            {
                return a + b;
            }
        }

Run the code and you will get 32 as output.


Here, we have the GetSum method, which will return the sum of two numbers. The result is then multiplied by 2. Hope you enjoyed reading it. Happy coding...!!!

Saturday, January 7, 2017

SingleOrDefault vs FirstOrDefault

LINQ provides with two extension methods SingleOrDefault and FirstOrDefault. Let's see the difference between the twoAdd a new class clsTest and add two properties Id and Name. Create a List clsTest type, add some data. So we have the following code:  
  1. static void Main(string[] args)  
  2.        {  
  3.            List<clsTest> lstTest = new List<clsTest>();  
  4.   
  5.            lstTest.Add(new clsTest  
  6.            {  
  7.                Id = 1,  
  8.                Name = "A"  
  9.            });  
  10.            lstTest.Add(new clsTest  
  11.            {  
  12.                Id = 2,  
  13.                Name = "B"  
  14.            });  
  15.            lstTest.Add(new clsTest  
  16.            {  
  17.                Id = 3,  
  18.                Name = "C"  
  19.            });  
  20.   
  21.   
  22.            var fod = lstTest.Where(l => l.Name == "D").FirstOrDefault();  
  23.            var sod = lstTest.Where(l => l.Name == "D").SingleOrDefault();  
  24.        }  
Here, we are access an element which does not exist in the list. Run the application and we get null. So both of these methods handle the null condition. Now let's add duplicate records and search the record. So the code changes to: 
  1. static void Main(string[] args)  
  2.         {  
  3.             List<clsTest> lstTest = new List<clsTest>();  
  4.   
  5.             lstTest.Add(new clsTest  
  6.             {  
  7.                 Id = 1,  
  8.                 Name = "A"  
  9.             });  
  10.             lstTest.Add(new clsTest  
  11.             {  
  12.                 Id = 2,  
  13.                 Name = "B"  
  14.             });  
  15.             lstTest.Add(new clsTest  
  16.             {  
  17.                 Id = 3,  
  18.                 Name = "C"  
  19.             });  
  20.             lstTest.Add(new clsTest  
  21.             {  
  22.                 Id = 4,  
  23.                 Name = "C"  
  24.             });  
  25.   
  26.             var fod = lstTest.Where(l => l.Name == "C").FirstOrDefault();  
  27.             var sod = lstTest.Where(l => l.Name == "C").SingleOrDefault();  
  28.         }  
Now run the application. We get the exception Sequence contains more than one element for SingleOrDefault. FirstOrDefault returns the first matching record i.e. the record with Id=3. However, This is because, SingleOrDefault cannot handle the situation if there are multiple elements with the same name. However, FirstOrDefault will return the first matching record from the list. Happy coding...!!!

Module ' ' is not available! You either misspelled the module name or forgot to load it. If registering a module ensure that you specify the dependencies as the second argument.

While learning angular-js, I came across the following error:

Module 'myApp' is not available! You either misspelled the module name or forgot to load it. If registering a module ensure that you specify the dependencies as the second argument.

The error seems to be straightforward that the module is not loaded. However, I cross-checked and found that module was there in the script and should have been loaded. My code looked like below:

  <table ng-app="myApp" ng-controller="testController">
        <tr ng-repeat="x in lstStrings">
            <td>{{ x }}</td>
        </tr>
    </table>

    <script type="text/javascript">
        var angApp = angular.module('myApp');
        angApp.controller('testController', function ($scope, $http) {
            $http.get('http://localhost:57964/api/test/getstringslist')
                  .then(function (response) {
                      $scope.lstStrings = response.data;
                  });
        });
    </script>

Then while comparing the code with some of the samples, I found that a very minor but very effective mistake which was causing the issues. The issue was that I was missing the second parameter of the angular.module function, So the missing part was the one highlighted below:

 <script type="text/javascript">
        var angApp = angular.module('myApp', []);
        angApp.controller('testController', function ($scope, $http) {
            $http.get('http://localhost:57964/api/test/getstringslist')
                  .then(function (response) {
                      $scope.lstStrings = response.data;
                  });
        });
    </script>

See how small the issue was, but it was the one that was breaking the application. As per official angular documentation, the second parameter is:

 This array is the list of modules myApp depends on.

This is a required parameter and can be specified as blank, if there is no dependency of other modules, on this one. Hope this helps somebody else also...!!! Happy coding.