Saturday, April 27, 2013

Friend Assemblies in C#


Occasionally you may want to access internal classes and their members found in one assembly from code in a separate assembly. The 'internal' modifier prevents this type of access. This restriction can be circumvented using C# 2.0 friend assemblies.

The Internal Modifier


The 'internal' access modifier can be applied to classes and their members to restrict their visibility to external objects. Internal items are available outside of the class but only to other items within the same assembly. Other assemblies are unaware of the internal elements. Sometimes you may wish to remove this restriction, allowing the internal classes and members in one assembly to be visible to other, specific assemblies. You may want to do this to split a large assembly into more manageable parts or to allow testing of internal items from a separate automated testing assembly. This can be achieved using friend assemblies.

NOTE: The use of friend assemblies is good for testing purposes. If you use friend assemblies for other purposes, you should consider your design to ensure that you are not breaking the rules of encapsulation.

Creating Friend Assemblies


Friend assemblies are created by adding an assembly attribute to the code. This attribute specifies the name of another assembly that will be granted access to internal members as if they were public. Any assemblies not specified will be prevented from accessing internal items. Private and protected classes and members always remain inaccessible.

To demonstrate, create a new, blank solution in Visual Studio named "FriendAssemblyDemo". Add two projects to this solution. The first should be a console application named "Caller" and the second should be a class library named "InternalsVisible". The Caller application will access an internal class in the InternalsVisible assembly. To link the two assemblies, add a reference to the class library within the console application.

We can now add an internal class to the InternalsVisible project. Modify the automatically created class file as follows:

Modify the Program class in the console application as shown below:
class Program
{
    static void Main(string[] args)
    {
        InternalsVisible.World world = new InternalsVisible.World();
        world.ShowMessage();
    }
}

If you attempt to compile the solution, you will see a compiler error. This error indicates that the InternalsVisible.World class cannot be accessed due to its protection level. To specify that the internals of the InternalsVisible project should be available to the Caller application, we need to add the following attribute to the class library's assembly. This line should appear outside of any namespace or class declaration.

NOTE: This attribute is found in the System.Runtime.CompilerServices namespace so ensure that the code file in which it appears includes the line, using System.Runtime.CompilerServices;

[assembly: InternalsVisibleTo("Caller")]

You should now be able to compile and execute the solution.

Working with Signed Assemblies


If the assembly that contains the internal items is signed with a public / private key pair, creating friend assemblies is more complicated. Firstly, you must sign any assemblies that access the signed code's internal members. Secondly, the InternalsVisibleTo attribute must be modified to include the public key, which is over three hundred characters in length.

 For example:
[assembly: InternalsVisibleTo("Caller, PublicKey=0024000004800000940000000602000000240000
525341310004000001000100655f087992abe9baf3d84d7bd066c98064b68633c1a7e1777d0e6c549c6c105a2
d9f03a0ca8076b42299b9da111e3e8efc5a02329959804e070e868b27263b7b5607d799553709fe4bb9d0d07c
e13b548b01dedf9afd033dda8e4a81639123160e7eb115cc0d16cb83c42b91affb029f846b07d86ec79b6b289
5b337f01d12b3")]

NOTE: The key must appear on a single line.

The public key can be obtained using the strong name tool in a two-stage process. Firstly, the public key must be extracted from the key file into a new file. This is achieved using the "p" switch. For example, if the key file is named "Caller.snk", you can copy the public key to a new file named "public.key" from the Visual Studio command line using the following command:

sn.exe -p Caller.snk public.key

The second stage is to view the contents of the new public key file in hexadecimal format. This can be outputted using the following command. The key value should then be copied and pasted into the assembly attribute.

sn.exe -tp public.key

Thursday, April 18, 2013

Tab between List elements WPF


<Window x:Class="TabInListView.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow"
        Height="350"
        Width="555"
        Loaded="Window_Loaded">
    <Grid>
        <ListView Name="lstDemo" KeyboardNavigation.TabNavigation="Continue">

            <ListView.ItemContainerStyle>
                <Style>
                    <Setter Property="KeyboardNavigation.IsTabStop" Value="False" />
                </Style>
            </ListView.ItemContainerStyle>

            <ListView.View>
                <GridView>

                    <GridViewColumn Header="Column1" Width="100" >
                        <GridViewColumn.CellTemplate>
                            <DataTemplate>
                                <TextBox Width="100" HorizontalAlignment="Stretch" Text="{Binding Path=Column1}"/>
                            </DataTemplate>
                        </GridViewColumn.CellTemplate>
                    </GridViewColumn>

                    <GridViewColumn Header="Column2" Width="100" >
                        <GridViewColumn.CellTemplate>
                            <DataTemplate>
                                <TextBox Width="100" HorizontalAlignment="Stretch" Text="{Binding Path=Column2}"/>
                            </DataTemplate>
                        </GridViewColumn.CellTemplate>
                    </GridViewColumn>

                    <GridViewColumn Header="Column3" Width="100" >
                        <GridViewColumn.CellTemplate>
                            <DataTemplate>
                                <TextBox Width="100" HorizontalAlignment="Stretch" Text="{Binding Path=Column3}"/>
                            </DataTemplate>
                        </GridViewColumn.CellTemplate>
                    </GridViewColumn>

                    <GridViewColumn Header="Column4" Width="100" >
                        <GridViewColumn.CellTemplate>
                            <DataTemplate>
                                <TextBox Width="100" HorizontalAlignment="Stretch" Text="{Binding Path=Column4}"/>
                            </DataTemplate>
                        </GridViewColumn.CellTemplate>
                    </GridViewColumn>

                    <GridViewColumn Header="Column5" Width="100" >
                        <GridViewColumn.CellTemplate>
                            <DataTemplate>
                                <TextBox Width="100" HorizontalAlignment="Stretch" Text="{Binding Path=Column5}"/>
                            </DataTemplate>
                        </GridViewColumn.CellTemplate>
                    </GridViewColumn>

                </GridView>
            </ListView.View>
        </ListView>
    </Grid>
</Window>

******************************************************************************

using System;
using System.Collections.Generic;
using System.Windows;
using System.Windows.Documents;

namespace TabInListView
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            try
            {
                List<Test> lst = new List<Test>();
                lst.Add(new Test { Column1="",Column2="",Column3="",Column4="",Column5=""});
                lst.Add(new Test { Column1 = "", Column2 = "", Column3 = "", Column4 = "", Column5 = "" });
                lst.Add(new Test { Column1 = "", Column2 = "", Column3 = "", Column4 = "", Column5 = "" });
                lst.Add(new Test { Column1 = "", Column2 = "", Column3 = "", Column4 = "", Column5 = "" });
                lst.Add(new Test { Column1 = "", Column2 = "", Column3 = "", Column4 = "", Column5 = "" });
                lst.Add(new Test { Column1 = "", Column2 = "", Column3 = "", Column4 = "", Column5 = "" });
                lst.Add(new Test { Column1 = "", Column2 = "", Column3 = "", Column4 = "", Column5 = "" });
                this.lstDemo.ItemsSource = lst;
            }
            catch (Exception)
            {
                throw;
            }
        }

        private class Test
        {
            public String Column1 { get; set; }
            public String Column2 { get; set; }
            public String Column3 { get; set; }
            public String Column4 { get; set; }
            public String Column5 { get; set; }
        }
    }
}

******************************************************************************


Monday, April 8, 2013

How to use Microsoft Enterprise Library in c#

Step 1:

First Download Microsoft Enterprise Library 5.0
http://www.microsoft.com/en-us/download/details.aspx?id=15104

Step 2:

Install Enterprise Library 5.0 in your system.

Step 3:

Create a test project named TestEnterpriseLibrary

Step 4:
Add following reference to your project
Microsoft.Practices.EnterpriseLibrary.Logging 
Step 5:
Add App.config file in your project 
Step 6:
Right click on app file and click on Edit Enterprise Library V5 Configuration

Step 7:

Go to Block then Add Logging Settings 


Step 8:

Expand the Logging Settings and do the following


Step 9:


Step 10:



Step 11:



Step 12:

Add Logging Filter 
If All Logging Enabled is set to true, log will write on file otherwise no log will maintain.  



Step 13:





using System;
using System.Diagnostics;
using Microsoft.Practices.EnterpriseLibrary.Logging;

namespace TestEnterpriseLibrary
{

    //********************************************************************************************************************************
    //                                                  Class:Log
    //********************************************************************************************************************************
    //                                     M O D I F I C A T I O N   M I L E S T O N E S
    // -------------------------------------------------------------------------------------------------------------------------------
    //  Date             |  Created By          | Description
    // --------+-------------------+--------------------------------------------------------------------------------------------------
    // Apr 02, 2013      | Kaushik Kumar Mistry | This Class is used to call the Interaction logic for Log
    //*********************************************************************************************************************************

    /// <summary>
    ///  This Class is used to call the Interaction logic for Log
    /// </summary>
    /// <Developer>Kaushik Kumar Mistry</Developer>
    /// <DateCreated>02 April 2012</DateCreated>
    public static class Log
    {

        public static void WriteException(Exception ex)
        {
            if (Logger.IsLoggingEnabled())
            {
                StackTrace stackTrace = new StackTrace(ex, true);   // Get call stack
                StackFrame[] stackFrames = stackTrace.GetFrames();  // Get method calls (frames)

                // write call stack method names
                foreach (StackFrame stackFrame in stackFrames)
                {
                    LogEntry loggerEntry = new LogEntry();
                    loggerEntry.TimeStamp = DateTime.Now;
                    loggerEntry.Message = String.Format("File Name: {0} Method: {1} Line: {2} Column: {3} Exception:{4}", stackFrame.GetFileName(), stackFrame.GetMethod().Name, stackFrame.GetFileColumnNumber(), stackFrame.GetFileLineNumber(), ex.ToString());
                    Logger.Write(loggerEntry);
                }
            }
        }

        public static void WriteException(Exception ex,String title)
        {
            if (Logger.IsLoggingEnabled())
            {
                StackTrace stackTrace = new StackTrace(ex, true);   // Get call stack
                StackFrame[] stackFrames = stackTrace.GetFrames();  // Get method calls (frames)

                // write call stack method names
                foreach (StackFrame stackFrame in stackFrames)
                {
                    LogEntry loggerEntry = new LogEntry();
                    loggerEntry.Title = title;
                    loggerEntry.TimeStamp = DateTime.Now;
                    loggerEntry.Message = String.Format("File Name: {0} Method: {1} Line: {2} Column: {3} Exception:{4}", stackFrame.GetFileName(), stackFrame.GetMethod().Name, stackFrame.GetFileColumnNumber(), stackFrame.GetFileLineNumber(), ex.ToString());
                    Logger.Write(loggerEntry);
                }
            }
        }
    }
}

******************************************************************


using System;

namespace TestEnterpriseLibrary
{
    class Program
    {
        static void Main(string[] args)
        {
            try
            {
                int divideBy = 0;
                int x = 1 / divideBy;
            }
            catch (Exception ex)
            {
                Log.WriteException(ex);
            }
            Console.Read();
        }
    }
}

******************************************************************


<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <configSections>
        <section name="loggingConfiguration" type="Microsoft.Practices.EnterpriseLibrary.Logging.Configuration.LoggingSettings, Microsoft.Practices.EnterpriseLibrary.Logging, Version=5.0.414.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" requirePermission="true" />
    </configSections>
    <loggingConfiguration name="" tracingEnabled="true" defaultCategory="General">
        <listeners>
            <add name="Event Log Listener" type="Microsoft.Practices.EnterpriseLibrary.Logging.TraceListeners.FormattedEventLogTraceListener, Microsoft.Practices.EnterpriseLibrary.Logging, Version=5.0.414.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
                listenerDataType="Microsoft.Practices.EnterpriseLibrary.Logging.Configuration.FormattedEventLogTraceListenerData, Microsoft.Practices.EnterpriseLibrary.Logging, Version=5.0.414.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
                source="Enterprise Library Logging" formatter="Text Formatter"
                log="" machineName="." traceOutputOptions="None" />
            <add name="Flat File Trace Listener" type="Microsoft.Practices.EnterpriseLibrary.Logging.TraceListeners.FlatFileTraceListener, Microsoft.Practices.EnterpriseLibrary.Logging, Version=5.0.414.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
                listenerDataType="Microsoft.Practices.EnterpriseLibrary.Logging.Configuration.FlatFileTraceListenerData, Microsoft.Practices.EnterpriseLibrary.Logging, Version=5.0.414.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
                fileName="C:\trace.log" formatter="Text Formatter" traceOutputOptions="DateTime" />
        </listeners>
        <formatters>
            <add type="Microsoft.Practices.EnterpriseLibrary.Logging.Formatters.TextFormatter, Microsoft.Practices.EnterpriseLibrary.Logging, Version=5.0.414.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
                template="Timestamp: {timestamp}{newline}&#xA;Message: {message}{newline}&#xA;Category: {category}{newline}&#xA;Priority: {priority}{newline}&#xA;EventId: {eventid}{newline}&#xA;Severity: {severity}{newline}&#xA;Title:{title}{newline}&#xA;Machine: {localMachine}{newline}&#xA;App Domain: {localAppDomain}{newline}&#xA;ProcessId: {localProcessId}{newline}&#xA;Process Name: {localProcessName}{newline}&#xA;Thread Name: {threadName}{newline}&#xA;Win32 ThreadId:{win32ThreadId}{newline}&#xA;Extended Properties: {dictionary({key} - {value}{newline})}"
                name="Text Formatter" />
        </formatters>
        <logFilters>
            <add type="Microsoft.Practices.EnterpriseLibrary.Logging.Filters.LogEnabledFilter, Microsoft.Practices.EnterpriseLibrary.Logging, Version=5.0.414.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
                enabled="true" name="Logging Enabled Filter" />
        </logFilters>
        <categorySources>
            <add switchValue="All" name="General">
                <listeners>
                    <add name="Flat File Trace Listener" />
                </listeners>
            </add>
        </categorySources>
        <specialSources>
            <allEvents switchValue="All" name="All Events" />
            <notProcessed switchValue="All" name="Unprocessed Category" />
            <errors switchValue="All" name="Logging Errors &amp; Warnings">
                <listeners>
                    <add name="Event Log Listener" />
                    <add name="Flat File Trace Listener" />
                </listeners>
            </errors>
        </specialSources>
    </loggingConfiguration>
</configuration>

Tuesday, April 2, 2013

Creating Custom Exceptions in c#


using System;
using System.Runtime.Serialization;  

    /// <summary>
    ///  This Class is used to call the Interaction logic for CustomException.
    /// </summary>
    /// <Developer>Kaushik Kumar Mistry</Developer>
    /// <DateCreated>02 April 2012</DateCreated>
    [Serializable]
    public class CustomException : Exception
    {

        #region <<  Constructors  >>

        /// <summary>
        /// Throw exception with out message
        /// </summary>
        public CustomException()
            : base() { }

        /// <summary>
        /// hrow exception with simple message
        /// </summary>
        /// <param name="message"></param>
        public CustomException(String message)
            : base(message) { }

        /// <summary>
        /// Throw exception with message format and parameters
        /// </summary>
        /// <param name="format"></param>
        /// <param name="args"></param>
        public CustomException(String format, params object[] args)
            : base(String.Format(format, args)) { }

        /// <summary>
        /// Throw exception with simple message and inner exception
        /// </summary>
        /// <param name="message"></param>
        /// <param name="innerException"></param>
        public CustomException(String message, Exception innerException)
            : base(message, innerException) { }

        /// <summary>
        /// Throw exception with message format and inner exception. Note that, the variable length params are always floating.
        /// </summary>
        /// <param name="format"></param>
        /// <param name="innerException"></param>
        /// <param name="args"></param>
        public CustomException(String format, Exception innerException, params object[] args)
            : base(String.Format(format, args), innerException) { }

        /// <summary>
        /// The last flavor of custom exception constructor is used during exception serialization/deserialization.
        /// </summary>
        /// <param name="info"></param>
        /// <param name="context"></param>
        protected CustomException(SerializationInfo info, StreamingContext context)
            : base(info, context) { }

        #endregion
    }