Thursday, April 19, 2012

MEF : A sophisticated CompositionProvider

Today, I am going to share a sophisticated composition provider which can be used in any enterprise application with MEF, and will handle all complication involved with different object creations.

Lets start with a definition of ICompositionProvider interface, it defines contract for a composition provider. A sophisticated composition provider should atleast following combination of methods and events.

 public interface ICompositionProvider
    {
        IEnumerable<Lazy<T>> GetExports<T>(string contractName);
        IEnumerable<Lazy<T>> GetExports<T>();
        IEnumerable<Lazy<T,TMetadata>> GetExports<T,TMetadata>();
        IEnumerable<Lazy<T>> GetExports<T>(string contractName, bool enableWildCards);
        IEnumerable<T> GetExportedValues<T>();
        IEnumerable<T> GetExportedValues<T>(string contractName);
        IEnumerable<T> GetExportedValues<T>(string contractName, bool enableWildCards);
        IEnumerable<T> GetEntitledExportedValues<T>(string contractName, bool enableWildCards);
        Lazy<T> GetExport<T>(string contractName);
        Lazy<T> GetExport<T>();
        void SatisfyImports(object attributedPart);
        void Compose(object attributedPart);
        event EventHandler FullyComposed;
        event EventHandler CompositionFailed;
    }
 
 
Lets look at a CompositionProvider class, CompositionProvider class implementation looks like
 
 public class CompositionProvider : ICompositionProvider
    {
        #region Private constants
 
        private const string CLASS_NAME = "CompositionProvider.";
        private const int MAX_TICKS = 100;
 
        private const string ENTITLEMENT_ASSEMBLY_NAME =
            "EntitlementModule.dll";
 
        private const string INFRASTRUCTURE_ASSEMBLY_NAME =
            "Infrastructure.dll";
 
 
        private const string AUTHENTICATION_ASSEMBLY_NAME =
            "AuthenticationModule.dll";
 
        private const string FAILED_COMPOSITION_MESSAGE = "Failed to compose part {0}";
 
        #endregion
 
        #region Variables
 
        public static CompositionProvider _Singleton;
        private readonly AggregateCatalog _aggergate = new AggregateCatalog();
        internal CompositionContainer Container { getprivate set; }
 
        public event EventHandler FullyComposed;
        public event EventHandler CompositionFailed;
 
        #endregion
 
        #region Static Properies
        /// <summary>
        /// It indicates current instance.
        /// </summary>
        internal static CompositionProvider Singleton
        {
            get { return _Singleton; }
        }
 
        #endregion
 
        #region Static Constructor
        /// <summary>
        /// Its a static constructor for CompositionProvider class.
        /// </summary>
        static CompositionProvider()
        {
            try
            {
                _Singleton = new CompositionProvider();
            }
            catch (Exception e)
            {
                ErrorHandler.HandleError(e, ErrorTypes.CriticalError);
            }
        }
 
        #endregion
 
        #region Constructor
 
        /// <summary>
        /// Its a constructor for CompositionProvider class.
        /// </summary>
        public CompositionProvider()
        {
            
            _aggergate.Catalogs.Add(new AssemblyCatalog(typeof(CompositionProvider).Assembly));
            Container = new CompositionContainer(_aggergate);
            Compose(this);
            
        }
 
        #endregion
 
        #region Methods
 
        public static void Start()
        {
        }
 
        /// <summary>
        /// It returns a lazy collection of passed type.
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        public IEnumerable<T> GetExportedValues<T>()
        {
            IEnumerable<T> value = GetExportedValues<T>(nulltrue);
            return value;
        }
 
        /// <summary>
        /// It returns a collection of passed contract name.
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="contractName"></param>
        /// <returns></returns>
        public IEnumerable<T> GetExportedValues<T>(string contractName)
        {
            IEnumerable<T> value = GetExportedValues<T>(contractName, false);
            return value;
        }
 
        /// <summary>
        /// It returns a collection of passed contract name with wild cards.
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="contractName"></param>
        /// <param name="enableWildCards"></param>
        /// <returns></returns>
        public IEnumerable<T> GetExportedValues<T>(string contractName, bool enableWildCards)
        {
 
            var value = new List<T>();
            try
            {
                if (contractName == null)
                {
                    value = Container.GetExportedValues<T>().ToList();
                }
                else
                {
                    if (enableWildCards)
                    {
                        Container.GetExportedValues<T>(contractName).ToList().ForEach(e => value.Add(e));
                        Container.GetExportedValues<T>(SystemConstants.SYSTEM_WILDCARD).ToList().ForEach(
                            e => value.Add(e));
                    }
                    else
                    {
                        value = Container.GetExportedValues<T>(contractName).ToList();
                    }
                }
            }
            catch (ImportCardinalityMismatchException importCardinalityMismatchException)
            {
                ErrorHandler.HandleError(importCardinalityMismatchException,
                                                              ErrorTypes.CriticalError);
            }
            catch (CompositionException compositionException)
            {
                ErrorHandler.HandleError(compositionException, ErrorTypes.CriticalError);
            }
             return value;
        }
 
        /// <summary>
        /// It returns a collection of passed contract name with wildcards.
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="contractName"></param>
        /// <param name="enableWildCards"></param>
        /// <returns></returns>
        public IEnumerable<Lazy<T>> GetExports<T>(string contractName, bool enableWildCards)
        {
            FrontEndTracing.Singleton.LogEntry(CLASS_NAME + " GetExports<T>(string contractName, bool enableWildCards)");
 
            List<Lazy<T>> value = default(List<Lazy<T>>);
            try
            {
                if (contractName == null)
                {
                    value = Container.GetExports<T>().ToList();
                }
                else
                {
                    if (enableWildCards)
                    {
                        Container.GetExports<T>(contractName).ToList().ForEach(e => value.Add(e));
                        Container.GetExports<T>(SystemConstants.SYSTEM_WILDCARD).ToList().ForEach(e => value.Add(e));
                    }
                    else
                    {
                        value = Container.GetExports<T>(contractName).ToList();
                    }
                }
            }
            catch (ImportCardinalityMismatchException e)
            {
                ErrorHandler.HandleError(e, ErrorTypes.CriticalError);
            }
 
            return value;
        }
 
        /// <summary>
        /// this will work with the entitlements provider to return a list of values for the type provided 
        /// using an entitlement attribute check for each value returned
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="contractName"></param>
        /// <param name="enableWildCards"></param>
        /// <returns></returns>
        public IEnumerable<T> GetEntitledExportedValues<T>(string contractName, bool enableWildCards)
        {
            var itemsToReturn = new List<T>();
            if (EntitlementProvider == null)
            {
                throw new NullReferenceException("The EntitlementsProvider is null so this can't work");
            }
             List<T> items = GetExportedValues<T>(contractName, enableWildCards).ToList();
 
            IEnumerable<Type> types = items.Select(v => v.GetType());
            foreach (T item in items)
            {
                object[] attributes = item.GetType().GetCustomAttributes(typeof (RequiresEntitlementAttribute), true);
                IEnumerable<RequiresEntitlementAttribute> requiresEntitlementAttributes =
                    attributes.Select(a => a as RequiresEntitlementAttribute);
                itemsToReturn.Add(item);
            }
 
            return itemsToReturn;
        }
 
        /// <summary>
        /// It returns lazy collection of passed contract name.
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="contractName"></param>
        /// <returns></returns>
        public IEnumerable<Lazy<T>> GetExports<T>(string contractName)
        {
            IEnumerable<Lazy<T>> value = GetExports<T>(contractName, false);
            return value;
        }
 
        /// <summary>
        /// It returns a object of passed type.
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        public IEnumerable<Lazy<T>> GetExports<T>()
        {
            IEnumerable<Lazy<T>> value = GetExports<T>(nulltrue);
            return value;
        }
 
        /// <summary>
        /// It returns a object of passed contract name.
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="contractName"></param>
        /// <returns></returns>
        public Lazy<T> GetExport<T>(string contractName)
        {
            Lazy<T> value = default(Lazy<T>);
            try
            {
                value = Container.GetExport<T>(contractName);
            }
            catch (ImportCardinalityMismatchException e)
            {
                ErrorHandler.HandleError(e, ErrorTypes.CriticalError);
            }
 
            return value;
        }
 
        /// <summary>
        /// It returns an object of passed type.
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        public Lazy<T> GetExport<T>()
        {
            Lazy<T> value = default(Lazy<T>);
            try
            {
                value = Container.GetExport<T>();
            }
            catch (ImportCardinalityMismatchException e)
            {
                ErrorHandler.HandleError(e, ErrorTypes.CriticalError);
            }
            
 
            return value;
        }
 
        public IEnumerable<Lazy<T,TMetadata>> GetExports<T,TMetadata>()
        {
            return this.Container.GetExports<T, TMetadata>();
        } 
 
        /// <summary>
        /// It composes passed object.
        /// </summary>
        /// <param name="attributedPart"></param>
        public void Compose(object attributedPart)
        {

 
            if (attributedPart != null)
            {
                try
                {
                    var batch = new CompositionBatch();
                    batch.AddPart(attributedPart);
                    Container.Compose(batch);
                }
                catch (CompositionException compositionException)
                {
                   ErrorHandelr.HandeError(compositionException);
                }
            }

        }
 
        /// <summary>
        /// This method is called when imports are satisfied.
        /// </summary>
        /// <param name="attributedPart"></param>
        public void SatisfyImports(object attributedPart)
        {
            if (attributedPart != null)
            {
                try
                {
                    var batch = new CompositionBatch();
                    batch.AddPart(attributedPart);
                    Container.SatisfyImportsOnce(batch);
                }
                catch (CompositionException compositionException)
                {
                    ErrorHandler.HandleError(compositionException, ErrorTypes.CriticalError);
                }
            }
        }
 
        /// <summary>
        /// It authenticate current user.
        /// </summary>
        public void Authenticate()
        {
            Assembly infraAssm = Assembly.LoadFrom(Constants.CompositionPath + INFRASTRUCTURE_ASSEMBLY_NAME);
            if (infraAssm != null)
            {
                _aggergate.Catalogs.Add(new AssemblyCatalog(infraAssm));
            }
 
            Assembly authAssm = Assembly.LoadFrom(Constants.CompositionPath + AUTHENTICATION_ASSEMBLY_NAME);
 
            if (authAssm != null)
            {
                _aggergate.Catalogs.Add(new AssemblyCatalog(authAssm));
                LoginManager.LoginCompleted += OnLoginCompleted;
                LoginManager.Login();
            }
            else
            {
                MessageBox.Show("Can't find the Authentication Module");
                SendFail();
            }

        }
 
        /// <summary>
        /// It sends fail method for logging.
        /// </summary>
        private void SendFail()
        {
             if (CompositionFailed != null)
            {
                CompositionFailed(thisEventArgs.Empty);
            }
        }
 
        public void OnLoginCompleted(object sender, LoginCompletedEventArgs e)
        {
            if (e.Message == "Cancel")
            {
                SendFail();
            }
            else if (e.ClientInformation.IsAuthenticated)
            {
                Current.SetClientContext(e.ClientInformation);
                Entitle();
            }

        }
 
 
        /// <summary>
        /// It calls entitlement provider for required keys.
        /// </summary>
        public void Entitle()
        {

            Assembly entitleAssm = Assembly.LoadFrom(Constants.CompositionPath + ENTITLEMENT_ASSEMBLY_NAME);
 
            if (entitleAssm != null)
            {
                _aggergate.Catalogs.Add(new AssemblyCatalog(entitleAssm));
                EntitlementProvider.EntitlementsLoaded += OnEntitlementsLoaded;
                EntitlementProvider.GetEntitlements();
                if (XamlUtility.IsInDesignMode()) return;
            }
            else
            {
                MessageBox.Show("Can't find the Entitlements Module");
                SendFail();
            }

        }
 
        /// <summary>
        /// Its called when entitlements are satisfied.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        internal void OnEntitlementsLoaded(object sender, EventArgs e)
        {
            //this._HasEntitlements = true;
            List<Assembly> assemblies = AppDomain.CurrentDomain.GetAssemblies().ToList();
            _aggergate.Catalogs.Clear();
            var directoryDlls = new DirectoryCatalog(Constants.CompositionPath, "*.dll");
            var directoryExes = new DirectoryCatalog(Constants.CompositionPath, "*.exe");
            foreach (string loadedFile in directoryDlls.LoadedFiles)
            {
                Assembly assm = Assembly.LoadFrom(loadedFile);
 
                assemblies.Remove(assm);
                _aggergate.Catalogs.Add(new AssemblyCatalog(assm));
            }
 
            foreach (string loadedFile in directoryExes.LoadedFiles)
            {
                Assembly assm = Assembly.LoadFrom(loadedFile);
 
                assemblies.Remove(assm);
                _aggergate.Catalogs.Add(new AssemblyCatalog(assm));
            }
 
            assemblies.ForEach(a => _aggergate.Catalogs.Add(new AssemblyCatalog(a)));
            if (FullyComposed == null)
            {
                SendFail();
                return;
            }
 
            FullyComposed(thisEventArgs.Empty);
        }
 
        #endregion
 
    } 

Friday, April 13, 2012

WPF : Determining if user is running same application instance on a terminal server

Please refer to this article in which I showed how we can determine if user is trying to run same application instance, this approach will work on single user Desktop machine, but it will not work when there are multiple users connecting to a terminal server and are trying to run same application. What happens is if a user start application, and then if some other user tries to start same application then it fails saying that application is already running because it doesn't distinguishes 2 users, so in this article I am going to show how we can change the old logic to consider individual user also.


private void Application_Startup(object sender, StartupEventArgs e)
{        
 string processname = Process.GetCurrentProcess().ProcessName + ".exe";
 string currentuserid = GetLoggedInUserName(); //This function should return Loggedin user name, you can put your logic here.
 totaluserapplicationinstance = 0;
 
 System.Management.ManagementObjectSearcher Processes = new System.Management.ManagementObject Searcher("SELECT * FROM Win32_Process Where Name ='" + processname + "'");
               
 foreach (System.Management.ManagementObject process in Processes.Get())
 {
  string[] OwnerInfo = new string[2];
  process.InvokeMethod("GetOwner", (object[])OwnerInfo);
  if (OwnerInfo[0].Equals(currentuserid))
  {
   totaluserapplicationinstance++;
  }
 }
 
 alreadyloggedin = totaluserapplicationinstance > 1;
 if (alreadyloggedin)
 {
  Messagebox.Show("You are already running an instance of same application");
  App.Current.Shutdown();
  return;
 }
}

Wednesday, March 28, 2012

WPF : Create a Hover over menu and show tab header in 2 lines for Infragistic Tab control

Requirement : In this post I am going to create a hover over menu, which will display a list of actions user can take whenever he moves his mouse over a textblock. I am also going to show how we can break tabheader text into 2 lines to reduce horizontal space taken by tab headers in Infragistic tab header contol.

Here is how application will look

Before user moves over Launch action



After user movers over Launch

Approach: I am going to create a user control which will use a label control ("lblLaunch" in my example) , a popup control which will hold a list of labels to indicates actions.

Here is my code for HoveroverMenu.xaml user control

<UserControl x:Class="CaseTrail.HoveroverMenu"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             mc:Ignorable="d" 
             Height="Auto" Width="Auto">
 <UserControl.Resources>
  <ControlTemplate x:Key="LabelControlTemplate1" TargetType="{x:Type Label}">
   <Border x:Name="brdName" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Padding="{TemplateBinding Padding}" SnapsToDevicePixels="True">
    <ContentPresenter ContentTemplate="{TemplateBinding ContentTemplate}" Content="{TemplateBinding Content}" ContentStringFormat="{TemplateBinding ContentStringFormat}" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" RecognizesAccessKey="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
                <Border.Background>
                    <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
                        <GradientStop Color="Black" Offset="1"/>
                        <GradientStop Color="#FFEDE7E7" Offset="0.196"/>
                    </LinearGradientBrush>
                </Border.Background>
            </Border>
   <ControlTemplate.Triggers>
    <Trigger Property="IsEnabled" Value="False">
     <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/>
    </Trigger>
                <Trigger Property="IsMouseOver" Value="True">
                    <Setter Property="Background" TargetName="brdName">
                        <Setter.Value>
                            <SolidColorBrush Color="#FFA7A2A2" />
                        </Setter.Value>
                    </Setter>
                </Trigger>
            </ControlTemplate.Triggers>
  </ControlTemplate>
 </UserControl.Resources>
    <StackPanel>
        <Label Width="100" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" x:Name="lblLaunch"  Grid.Column="1" Mouse.MouseMove="Button_MouseMove">
            <Label.Background>
          <LinearGradientBrush EndPoint="0,1" StartPoint="0,0">
           <GradientStop Color="#FFF3F3F3" Offset="0"/>
           <GradientStop Color="#FFEBEBEB" Offset="0.5"/>
           <GradientStop Color="#FFDDDDDD" Offset="0.5"/>
           <GradientStop Color="#FF45479F" Offset="1"/>
          </LinearGradientBrush>
            </Label.Background>
            
            <Label.Content>
                <StackPanel Orientation="Horizontal">
                    <TextBlock Text="Launch"></TextBlock>
                    <Path Margin="10,4,0,0"  Data="M160,24 L175.5,23.5 167.5,31.5 z" Fill="Blue" HorizontalAlignment="Left" Stretch="Fill" Stroke="Black" VerticalAlignment="Top" />
                </StackPanel>
            </Label.Content>
        </Label>
        
        <Popup Width="100"  x:Name="controls" StaysOpen="False"  >
            <ItemsControl Background="AliceBlue">
                <Label HorizontalContentAlignment="Center" Mouse.MouseDown="Label_MouseDown" VerticalContentAlignment="Center" HorizontalAlignment="Stretch" Content="Client Cases" Template="{DynamicResource LabelControlTemplate1}" />
                <Label HorizontalContentAlignment="Center" Mouse.MouseDown="Label_MouseDown" Template="{DynamicResource LabelControlTemplate1}"  VerticalContentAlignment="Center" HorizontalAlignment="Stretch" Content="Forms &amp; Letters" />
                <Label HorizontalContentAlignment="Center" Mouse.MouseDown="Label_MouseDown" Template="{DynamicResource LabelControlTemplate1}"  VerticalContentAlignment="Center" HorizontalAlignment="Stretch" Content="Search Rep." />
                <Label HorizontalContentAlignment="Center" Mouse.MouseDown="Label_MouseDown" Template="{DynamicResource LabelControlTemplate1}"  VerticalContentAlignment="Center" HorizontalAlignment="Stretch" Content="Log Call" />
            </ItemsControl>
        </Popup>
 
    </StackPanel>
</UserControl> 
 
 
 Here is my code for HoveroverMenu.xaml.cs file
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
 
namespace CaseTrail
{
    /// <summary>
    /// Interaction logic for HoveroverMenu.xaml
    /// </summary>
    public partial class HoveroverMenu : UserControl
    {
        public HoveroverMenu()
        {
            InitializeComponent();
        }
 
        private void Button_MouseMove(object sender, MouseEventArgs e)
        {
            if (!controls.IsOpen)
            controls.IsOpen = true;
        }
 
        private void Label_MouseDown(object sender, MouseButtonEventArgs e)
        {
            Label l = e.Source as Label;
            MessageBox.Show(l.Content.ToString());
        }
    }
} 
 
 
I am going to use my HoveroverMenu control in my view MainWindow.xaml file as shown below
 
<Window
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:igWindows="http://infragistics.com/Windows" xmlns:Microsoft_Windows_Themes="clr-namespace:Microsoft.Windows.Themes;assembly=PresentationFramework.Aero" x:Class="CaseTrail.MainWindow"
    xmlns:local="clr-namespace:CaseTrail"    
    Title="MainWindow" Height="350" Width="625">
    
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition />
            <ColumnDefinition Width="Auto"/>
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto" />
            <RowDefinition />
        </Grid.RowDefinitions>
        <igWindows:XamTabControl VerticalAlignment="Stretch" Grid.RowSpan="2" Grid.ColumnSpan="2" x:Name="xamTabControl1"  Theme="Office2k7Blue" ShowTabHeaderCloseButton="True" AllowTabClosing="True"   >
            
            <igWindows:TabItemEx  MaxWidth="100"   >
                <igWindows:TabItemEx.Header>
                    <TextBlock MaxWidth="100" Height="35" TextWrapping="Wrap" Text="Case (Opened)"></TextBlock>
                </igWindows:TabItemEx.Header>
                <Grid />
            </igWindows:TabItemEx>
 
            <igWindows:TabItemEx  MaxWidth="100"   >
                <igWindows:TabItemEx.Header>
                    <TextBlock MaxWidth="100" Height="35" TextWrapping="Wrap" Text="Merge"></TextBlock>
                </igWindows:TabItemEx.Header>
                <Grid />
            </igWindows:TabItemEx>
            <igWindows:TabItemEx  MaxWidth="100"   >
                <igWindows:TabItemEx.Header>
                    <TextBlock MaxWidth="100" Height="35" TextWrapping="Wrap" Text="Clone"></TextBlock>
                </igWindows:TabItemEx.Header>
                <Grid />
            </igWindows:TabItemEx>
            <igWindows:TabItemEx MaxWidth="100"   >
                <igWindows:TabItemEx.Header>
                    <TextBlock MaxWidth="100" Height="35" TextWrapping="Wrap" Text="Related"></TextBlock>
                </igWindows:TabItemEx.Header>
                <Grid />
            </igWindows:TabItemEx>
            <igWindows:TabItemEx  MaxWidth="100"   >
                <igWindows:TabItemEx.Header>
                    <TextBlock MaxWidth="100" Height="35" TextWrapping="Wrap" Text="Related Cases"></TextBlock>
                </igWindows:TabItemEx.Header>
                <Grid />
            </igWindows:TabItemEx>
            <igWindows:TabItemEx MaxWidth="100"  >
                <igWindows:TabItemEx.Header>
                    <TextBlock MaxWidth="100" Height="35" TextWrapping="Wrap" Text="Client View"></TextBlock>
                </igWindows:TabItemEx.Header>
                <Grid />
            </igWindows:TabItemEx>
        </igWindows:XamTabControl>
        
        <local:HoveroverMenu Grid.Column="1" Margin="0,5,5,0" />
           
    </Grid>
</Window> 
 
 
 
 

Thursday, March 22, 2012

WPF (C#) : Make sure only one instance of your application is running

In this article I am going to show how to figure out if your application is already running and you don't want to start a new instance of application.
I am going to write this method in Application_Startup event in WPF, but this logic can be used in Winforms also.

In Your Application_Startup , Check if there is already a process running which has same name like your process and if yes then that means application is already running and exit.

Here is sample App.xaml.cs file


public partial class App : Application
    {
        #region Variables
        bool alreadyloggedin = false;
        #endregion
 
        #region Events
 
 
        private void Application_Startup(object sender, StartupEventArgs e)
        {
 
            Process[] processlist = Process.GetProcessesByName(Process.GetCurrentProcess().ProcessName);
            alreadyloggedin = processlist.Length > 1;
 
          
 
            if (alreadyloggedin)
            {
                MessageBox.Show("Application is already running");
                App.Current.Shutdown();
                return;
            }
 
            
        }
 
       
 
        #endregion
    }

Wednesday, March 21, 2012

Design/Coding Principal "KISS" : Keep it Simple Stupid

Today I am going to talk about KISS design principal, visit this wiki site for introduction.
I am  going to talk about it more from Real life experience in coding.

I had a junior developer in my team, he was given a task of writing a search operation in UI and I was surprised when i heard him talking about making a simple code look complicated just because he though writing it complicated way will give him some advantage over performance. But when we do something like this we forget that if we try to make something unrealistically complicated then it will make our unit testing tough, it will make maintenance of code tough and most important thing we hardly get any performance improvement.

so put it altogether we should follow KISS principal for following benefits
1) Makes unit testing simple
2) Helps in easy maintenance
3) Makes easy code review
4) Makes commenting easy