Monday, March 31, 2014

Getting unique records based on property from list without using Distinct() in Linq

The scenario is very simple. We have a collection of Person objects. We want to know the unique PersonTypes from the collection. Below the Person class definition.

    public class Person
    {
        [Display(Name = "First Name")]
        public string PersonType { getset; }
        public XElement Properties { getset; }
    }
    public class PersonType
    {
        public string TypeName { getset; }
    }

I don't think nobody will write a loop to achieve this. The normal solution we may think of is to get the distinct Person objects using the Distinct function in Linq. But it requires an IEqualityComparer derived object to handle the comparison which is employed to find the duplicates by the Distinct function. I have explained about IEqualityComparer in one of my previous posts related to merging 2 collections without duplicates.

        static internal IEnumerable<PersonType> GetUniquePersonTypes()
        {
            IEnumerable<PersonType> personTypesList = _persons.Distinct(new PersonComparer())
                                                                                                .Select(per=>new PersonType(){TypeName=per.PersonType});
            return personTypesList;
        }
   public  class PersonComparer:IEqualityComparer<Person>
    {
        bool IEqualityComparer<Person>.Equals(Person person1, Person person2)
        {
            return person1.PersonType.Equals(person2.PersonType);
        }
 
        int IEqualityComparer<Person>.GetHashCode(Person person)
        {
            return person.PersonType.GetHashCode();
        }
    }

GroupBy to find distinct objects based on entity property

Should we really need Distinct and another class which implements IEqualityComparer? If we group the list based on the property which is key to decide duplicate and build a collection out of the group keys, won't that be same result of Distinct with comparer? Lets try it.

        static internal IEnumerable<PersonType> GetUniquePersonTypes()
        {
            IEnumerable<PersonType> personTypesList= _persons.GroupBy(x => x.PersonType)
                                                                                            .Select(group => new PersonType() 
                                                                                                                { TypeName = group.Key }
                                                                                            );
            return personTypesList;
        }

Is it working? Happy coding

Tuesday, March 25, 2014

If statement in SQLCMD

SQLCMD is a nice utility to automate the SQL scripts execution.I became the fan of it years ago when I first used it for automating database creation and version upgrade of databases. The past sql automations using sqlcmd.exe were relatively simple. Most of those were using tokens and those tokens will be replaced with actual values when the execution starts. The values for tokens will be supplied by initiating programs and those programs may be of .bat, .vbs or .ps1 files at the most it will be invoked from the installers.

Recently we came to a situation where a branching is required in SQLCMD scripting. Basically we need to change the value of the token at runtime based no a database SELECT query. At that moment I realized that sqlcmd doesn't have branching statements. Team's initial decision to mitigate it was to call the database from the initiator programs.But those will make the .bat files really heavy or may need to write another PowerShell script or exe to do the job and get the value for sqlcmd token.

But a tight google exercise unveiled the below link which explains how to imitate the branching in sqlcmd. Its nothing but creating dynamic .sql file based on query result and executing the same from its creator sql file. I don't think I need to replicate the details again. So just open the link and have fun.


Tuesday, March 18, 2014

.Net Assembly versioning in Plug-in framework

As everybody knows assembly versioning in .net is a good concept. It helps us to deliver upgraded versions very easily without affecting behaviour of old versions ie easier to maintain backward compatibility. It also helps us to sign our assemblies with strong name which means our delivered dlls are unique.

In normal cases, the assembly version contains 4 numbers separated by period "." . Those denote Major version,Minor version, Build number and Revision number respectively. When to change or increment the assembly version is a tough decision especially when it comes to applications which uses reflection extensively. As best practices some people changes the assembly version for the shipping builds only. Anyhow when we change the assembly version we need to make sure that all assemblies including dependent assemblies are loading correctly as those are signed and needs to be in same version.

In my current project we are changing the assembly version once in a year as we are using reflection in its maximum. Recently we had to deal with a versioning issue related to a plug-in architecture, we introduced last year. For simplicity I can explain the plug-in architecture using simple drawing application framework which uses IShape and its implemented classes.

Problem

The aim is to have a plug-in architecture in place where there will be a framework which will be always latest. There will be an interface IShape with a method Draw().The framework creates the object of IShape implemented classes based on configuration using reflection and calls its Draw() method. We released it in 2013 and the structure was as follows
  • Core.dll {Version:1.0.0.0}
    • Contains IShape interface
  • Framework.exe{1.0.0.0}
    • The controller class which creates the object of IShape using reflection and call Draw()
  • Impl10.dll{Verion:1.0.0.0}
    • Contains Circle class which implements IShape.Draw() method to draw circle shape.
In 2014 we are not supposed to release Impl10.dll as there is no change. But the Framework.exe might have feature improvements and it's version needs to be incremented. Similarly the version of Core.dll needs to be incremented as its always expected to be latest.

The problem starts from here. If we deliver the new version of Core and Framework with incremented assembly version 2.0.0.0 for Core.dll and Framework.dll, the Impl10.dll will not get loaded as its in old version.

Dlls present after new release.
  • Core.dll {Version:2.0.0.0}
    • Contains IShape interface
  • Framework.exe{2.0.0.0}
    • The controller class which creates the object of IShape using reflection and call Draw()
  • Impl10.dll{Verion:1.0.0.0}
    • Contains Circle class which implements IShape.Draw() method to draw circle shape
  • Impl20.dll{Version 2.0.0.0}
    • Contains Rectangle class which implements IShape.Draw() method to draw rectangle shape

Possible solutions

  1. Assembly binding redirection 
    Using this technique we are forcing the .net runtime to use latest version of Core.dll even for Impl10.dll which is pointing towards previous version of Core.dll .But needs to maintain list of all old versions.
  2. Manual Assembly resolution
    This technique loads the assembly by writing the assembly loading code in the AppDomain.AssemblyResolve event.
  3. Constant version for Core.dll
    Simple one. Don't change the version of Core.dll even there are changes for new features. So that always the classes are implementing same interface. The assembly version of implementing classes can be incremented.
We opted the 3rd solution as its simple. Attached a sample which explains the plug-in scenario.


Things to remember

When we select any of these options we need to make sure below points
  1. Never remove any method or change the method signature in interface methods. If we do so .net runtime verification will fail and it will throw method not found exceptions if we try to load old assemblies.
  2. If we want to add more methods to the interface, we need to create new interface inheriting from IShape and have new methods there. When creating objects in framework.exe make sure we cast to respective interfaces to invoke operations. Since deployed framework.exe will be always latest, it can be done easily.

Monday, March 10, 2014

Not able to start Android application after adding activity through new Wizard in Eclipse

I normally add new Android activities, corresponding classes and config changes manually. Recently I came to visit a link from Kerala start-up village blog where they were explaining how to create new activity in Android. They mentioned in the same way I am doing. Or probably most of the developers are doing. Then I thought of other easy ways using Eclipse IDE or the Android plug-in to generate activity xml, its class and changes in the AndroidManifest and could see Android help page which explains the same. 

Just thought of trying it out by creating an activity into one of my Android project. After creating the activity, I was not able to run the application in simulator. The error got in the Console window is given below .

[time - app name] Installation error: INSTALL_PARSE_FAILED_MANIFEST_MALFORMED
[time - app name] Please check logcat output for more details.
[time - app name] Launch canceled!

It suggests to check the logcat as well. So opened the logcat window and log reads as follows.

<time>: W/ActivityManager(407): No content provider found for permission revoke: file:///data/local/tmp/<name>.apk
<time>: I/PackageManager(407): Copying native libraries to /data/app-lib/vmdl-1401938519
<time>: W/PackageParser(407): /data/app/vmdl-1401938519.tmp (at Binary XML file line #12): <activity> does not have valid android:name

Here the console logs says that the manifest is malformed. In logcat window we could see 2 issues. One error says permission issue. And second line says activity does not have valid android:name property value. It means the activity which I added via the android wizard might have added incorrect entry to the android manifest xml file.

I started by googling the error message. Most of the SO links says its permission issue and I have to give full permission to C:\Users\<user name>\.android folder. I checked and could see it has full permission. Then I compared my faulty project's androidmanifest.xml file with other project and could see that the Android wizard which used to add activity has added the package name to the android:name. Earlier the name was .activityname. The wizard updated the activity name as packagename.activityname which caused the problem. Since the package name is already mentioned in the manifest root node, activity name cannot have the package name.

A sample has been given below

Wrong xml
<activity
            android:name="JoymonOnline.Malayalam.SwipeHost"
            android:label="@string/title_activity_swipe_host" >
</activity>

Corrected the android:name

<activity
            android:name=".SwipeHost"
            android:label="@string/title_activity_swipe_host" >
</activity>

Happy coding. 

Monday, March 3, 2014

Cloud based VisualStudio Online TFS - Some recipes to work with it

I started using Microsoft's FREE cloud based Visual Studio Online TFS when my company's TFS server got crashed and the situation continued for couple of weeks. Since we were doing some research projects, we didn't feel the source is something must be kept in company TFS. Only problem we faced was the number of team members are limited in free TFS Cloud account. But since most of us were not actively participating in the development, we were able to live with 5 people tfs team.

Now the in-house TFS is up and I am in the process of moving the source to company tfs. I moved one project and then thought of deleting it from my personal cloud tfs. Since the TFS online  is new, it was little difficult to find help. Actually its not about finding help. Its about the user experience of Visual Studio online portal. If the user experience is good, the presense of help documents doesn't matter. But it seems the team has done good job in updating MSDN with the help. Since the direct google doesn't give the links, I thought of posting the same here. So below are some common tasks and how it can be done if we are using Visual Studio Online TFS.

Visual Studio Online, TFS Online, Cloud based TFS are all same. If you want can start creating your own team projects by signing into www.VisualStudio.com with your live id.