Pages

Wednesday, January 5, 2011

Custom Attributes




Why Attributes?

                                Attributes are elements that allow you to add declarative information to your programs. This declarative information is used for various purposes during runtime and can be used at design time by application development tools. For example, there are attributes such as DllImportAttribute that allow a program to communicate with the Win32 libraries. Another attribute, ObsoleteAttribute, causes a compile-time warning to appear, letting the developer know that a method should no longer be used. When building Windows forms applications, there are several attributes that allow visual components to be drag-n-dropped onto a visual form builder and have their information appear in the properties grid. 

                               Attributes are also used extensively in securing .NET assemblies, forcing calling code to be evaluated against pre-defined security constraints.

                                 The reason attributes are necessary is because many of the services they provide would be very difficult to accomplish with normal code. You see, attributes add what is called metadata to your programs. When your C# program is compiled, it creates a file called an assembly, which is normally an executable or DLL library. Assemblies are self-describing because they have metadata written to them when they are compiled. Via a process known as reflection, a program's attributes can be retrieved from its assembly metadata. Attributes are classes that can be written in C# and used to decorate your code with declarative information. This is a very powerful concept because it means that you can extend your language by creating customized declarative syntax with attributes.

When do we need attributes ?

                                   The advantage of using attributes resides in the fact that the information that it contains is inserted into the assembly. This information can then be consumed at various times for all sorts of purposes:

  1. An attribute can be consumed by the compiler. The System.ObsoleteAttribute attribute that we have just described is a good example of how an attribute is used by the compiler, certain standard attributes which are only destined for the compiler are not stored in the assembly. For example, the SerializationAttribute attribute does not directly mark a type but rather tells the compiler that type can be serialized. Consequently, the compiler sets certain flags on the concerned type which will be consumed by the CLR during execution such attributes are also named pseudo-attributes.
  2. An attribute can be consumed by the CLR during execution. For example the .NET Framework offers the System.ThreadStaticAttribute attribute. When a static field is marked with this attribute the CLR makes sure that during the execution, there is only one version of this field per thread.
  3. An attribute can be consumed by a debugger during execution. Hence, the System.Diagnostics.DebuggerDisplayAttribute attribute allows personalizing the display of an element of the code(the state of an object for example) during debugging.
  4. An attribute can be consumed by a tool, for example, the .NET framework offers the System.Runtime.InteropServices.ComVisibleAttribute attribute. When a class is marked with this attribute, the tlbexp.exe tool generates a file which will allow this class to be consumed as if it was a COM object.
  5. An attribute can be consumed by your own code during execution by using the reflection mechanism to access the information. For example, it can be interesting to use such attributes to validate the value of fields in your classes. Such a field must be within a certain range. Another reference field must not be null. A string field can be atmost 100 character. Because of the reflection mechanism, it is easy to write code to  validate the state of any marked fields. A little later, we will show you such an example where you can consume attributes by your own code.
  6. An attribute can be consumed by a user which analyses an assembly with a tool such as ildasm.exe or Reflector. Hence you could imagine an attribute which would associate a character string to an element of your code. This string being contained in the assembly, it is then possible to consult these comments without needing to access source code.

Developing Custom Attributes

                             Derive our attribute class from System.Attribute class as stated in C# language specification . A class that derives from the abstract class System.Attribute, whether directly or indirectly, is an attribute class. The declaration of an attribute class defines a new kind of attribute that can be placed on a declaration.

Note: it is a convention to use the word Attribute as a suffix in attribute class names. However, when we attach the attribute to a program entity, we are free not to include the Attribute suffix. The compiler first searches the attribute in System.Attribute derived classes. If no class is found, the compiler will add the word Attribute to the specified attribute name and search for it.

Defining or Controlling Usage of Attribute

                          AttributeUsage class is another pre-defined class that will help us in controlling the usage of our custom attributes. That is, we can define attributes of our own attribute class. It describes how a custom attribute class can be used. AttributeUsage has three properties which we can set while placing it on our custom attribute. The first property is:

ValidOn

                       Through this property, we can define the program entities on which our custom attribute can be placed. The set of all possible program entities on which an attribute can be placed is listed in the AttributeTargets enumerator. We can combine several AttributeTargets values using a bitwise OR operation.

AllowMultiple

                       This property marks whether our custom attribute can be placed more than once on the same program entity.

Inherited

                        We can control the inheritance rules of our attribute using this property. This property marks whether our attribute will be inherited by the class derived from the class on which we have placed it.

Example:

using System;
[AttributeUsage(AttributeTargets.Class), AllowMultiple =
false,
Inherited =
false ]public class HelpAttribute : Attribute
{
   
public HelpAttribute(String Description_in)
    {
       
this.description = Description_in;
    }
   
protected String description;
   
public String Description
    {
       
get
        {
           
return this
.description;
        }           
    }   
}
[Help("this is a do-nothing class")]
public class AnyClass
{
}



Example for Querying Attributes at Run-Time

using System;
using System.Reflection;
using System.Diagnostics;

//
attaching Help attribute to entire assembly[assembly : Help("This Assembly demonstrates custom attributes
creation and their run-time query."
)]

//
our custom attribute classpublic class HelpAttribute : Attribute
{
    public HelpAttribute(String Description_in)
    {
        //

        // TODO: Add constructor logic here        this.description = Description_in;
        //

    }
    protected String description;
    public String Description
    {
        get
        {
            return this.deescription;
                
        }           
    }   
}
//
attaching Help attribute to our AnyClass[HelpString("This is a do-nothing Class.")]
public class AnyClass
{
//
attaching Help attribute to our AnyMethod    [Help("This is a do-nothing Method.")]
    public void AnyMethod()
    {
    }
//
attaching Help attribute to our AnyInt Field    [Help("This is any Integer.")]
    public int AnyInt;
}
class QueryApp
{
   
public static void
Main()
    {
        HelpAttribute HelpAttr;

       
//
Querying Assembly Attributes        String assemblyName;
        Process p = Process.GetCurrentProcess();
        assemblyName = p.ProcessName +
".exe"
;

        Assembly a = Assembly.LoadFrom(assemblyName);

       
foreach (Attribute attr in a.GetCustomAttributes(true
))
        {
            HelpAttr = attr
as
HelpAttribute;
           
if (null
!= HelpAttr)
            {
                Console.WriteLine(
"Description of {0}:\n{1}"
,
                                  assemblyName,HelpAttr.Description);
            }
        }
}
}

Monday, December 13, 2010

Dot Net - Delegate

What?

Its an object which allows you to reference a method.Using a delegate allows the programmer to encapsulate a reference to a method inside a delegate object. The delegate object can then be passed to code which can call the referenced method, without having to know at compile time which method will be invoked.

Actualy its like a pointer in C or C++ but delegate is not a pointer in C#, its an object so we can create the insatnce of delegate by using 'new' keyword. And also unlike function pointers in C or C++, delegates are object-oriented, type-safe, and secure.

An interesting and useful property of a delegate is that it does not know or care about the class of the object that it references. Any object will do; all that matters is that the method's argument types and return type match the delegate's. This makes delegates perfectly suited for "anonymous" invocation.

NOTE : Delegates run under the caller's security permissions, not the declarer's permissions.

Why?
  • Giving you maximum flexibility to implement any functionality you want at runtime.
  • The association between delegate and methods referenced by delegate is established in runtime - so, you get flexibility here.
  • Multi-cast: That's to associate a few methods/functions to ONE delegate. Invoking one delegate fires off ALL methods referenced by that one delegate all at once.
  • The use of delegates promotes good separation of functionality between the business layer/anyother layer and the client code. The client code has no knowledge of how logics works in other layer.
How to decide When to use Delegate OR Interface(Method)?

Delegates are useful when:
  • A single method is being called.
  • A class may want to have multiple implementations of the method specification.
  • It is desirable to allow using a static method to implement the specification.
  • An event-like design pattern is desired.
  • The caller has no need to know or obtain the object that the method is defined on.
  • The provider of the implementation wants to "hand out" the implementation of the specification to only a few select components.
  • Easy composition is desired.
Interfaces are useful when:
  • The specification defines a set of related methods that will be called.
  • A class typically implements the specification only once.
  • The caller of the interface wants to cast to or from the interface type to obtain other interfaces or classes.
Step to Implimentation Delegate?

  1. Declaring a delegate   
          public delegate void ProcessBookDelegate(Book book);

                                      Each delegate type describes the number and types of the arguments, and the type of the return value of methods that it can encapsulate.Whenever a new set of argument types or return value type is needed, a new delegate type must be declared.

   2.    Instantiating a delegate  

bookDB.ProcessPaperbackBooks(new ProcessBookDelegate(PrintTitle));
     
Note that once a delegate is created, the method it is associated with never changes — delegate objects are immutable. 

  3.   Calling a delegate   

   delegateObject(argument)


Reference:
http://msdn.microsoft.com/en-us/library/aa288459(v=vs.71).aspx

Friday, December 10, 2010

DotNet - IComparer Interface

What is IComparer?

Its an interface which Exposes a method that compares two objects.This interface is used in conjunction with the Collection.Sort and Array.BinarySearch methods. It provides a way to customize the sort order of a collection. This interface has a method 'Compare' which Compares two objects and returns a value indicating whether one is less than, equal to, or greater than the other.

Basicaly this interface uses for sorting the collection of custome object by one of their property.


Example : For soting a collection.

public class GenericComparer : IComparer
{
    private String _Property = null;
    private SortOrderEnum _SortOrder = SortOrderEnum.Ascending;
   
    public String SortProperty
    {
        get { return _Property; }
        set { _Property = value; }
    }

    public SortOrderEnum SortOrder
    {
        get { return _SortOrder; }
        set { _SortOrder = value; }
    }

    public int Compare(object x, object y)
    {
        Fruit ing1;
        Fruit ing2;
       
        if (x is Fruit)
            ing1 = (Fruit) x;
        else
            throw new ArgumentException("Object is not of type Fruit");

        if (y is Fruit)
            ing2 = (Fruit) y;
        else
            throw new ArgumentException("Object is not of type Fruit");
       
        if (this.SortOrder.Equals(SortOrderEnum.Ascending))
            return ing1.CompareTo(ing2, this.SortProperty);
        else
            return ing2.CompareTo(ing1, this.SortProperty);
    }
}


The sort order enumeration.

public enum SortOrderEnum
{
    Ascending,
    Descending
}

Now we can use this comparer in our sort method like

public void Sort(String SortBy, SortOrderEnum SortOrder)
{
    GenericComparer comparer = new GenericComparer();
    comparer.SortProperty = SortBy;
    comparer.SortOrder = SortOrder;
    this.InnerList.Sort(comparer);
}

Reference :

http://www.codeproject.com/KB/cs/GenericComparer.aspx

Thursday, December 9, 2010

SQL Server - Transaction Isolation Levels

What is Transaction Isolation?

In database systems, isolation is a property that defines how/when the changes made by one operation become visible to other concurrent operations. Isolation is one of the ACID (Atomicity, Consistency, Isolation, Durability) properties.

In very simple terms Isolation Levels decide “What happens when some data being referred to (for reading or writing) within an incomplete transaction is also being referred to (for reading or writing) from another connection (or user – actually it is called another ‘transaction lock space)".

Why Transaction Isolation Level required?
  • To avoid dirty read.
  • To avoid non repeatable read.
  • To avoid phantom rows read.
  1. Dirty read                 
                       This is when connections outside the transaction space can read the uncommitted data. You don’t want this to happen in most cases. The only reason when you may want to allow this is when you are creating a report which assumes a certain amount of inaccuracy. You think this situation is rare? Not really. Suppose the report compares the current month sale with last month sale and returns a percentage difference. Consider that the report takes 5 minutes to generate. During these 5 minutes, more transactions may be getting added to the sales data. Typically 5 transactions would get added to the sales table. The average transaction value is Rs. 1000. The total sale for the month is typically 30-40 lacs. In such cases, you really don’t need to worry about absolute accuracy. You can intentionally allow dirty reads because the impact is really not significant from a business perspective.

2.  Non-repeatable read

                       Within a transaction, the same data read any number of times should yield consistent results. If it is not same then the reads are ‘non-repeatable’.

3. Phatom Read

                       If you have already read a range of data based upon a key value, another transaction inserts a new row which happens to have a value between this range. The original range which was referred to would now become invalid. This is because a “Phantom row” was added. This is also a major problem.

How to set the Transaction Isolation Level?

SET TRANSACTION ISOLATION LEVEL { READ COMMITTED
| READ UNCOMMITTED
| REPEATABLE READ
| SERIALIZABLE
}


Example :  SET TRANSACTION ISOLATION LEVEL READ COMMITTED

Different Types of Isolation Level?




1. Read Uncommitted

All data which is uncommitted is readable from any connection. This should not be used unless you have a very good reason to do so.

Limitations:
  • Dirty-reads
  • Lost Updates
  • Phantom reads
  • Non-repeatable reads
Advantages:
  • Higher Concurrency

2. Read Committed

Although it is the default, it does not mean that this isolation level is ideal for all transactions. One of the regular tendencies amongst techies is to simply use default values without giving it a second thought! I cannot imagine the number of phantom and non-repeatable reads that must be occurring in the world because someone simply used the ‘default’ value. It is a scary thought to say the least.
This level is obviously more restrictive than the ‘Read Uncommitted’ level.

Limitations:
  • Lower Concurrency than ReadUncommitted
  • Lost Updates
Advantage:
  • Eliminates Dirty Reads
3. Repeatable read

This prevents dirty reads as well as non-repeatable reads. It does not prevent phantom rows. This is more restrictive than Read Committed level. When I say restrictive what does it mean? It means that the chances of other transactions having to wait for this one to finish are INCREASED. Another way of saying this is – Repeatable Read reduces concurrency compared to Read Committed level.
This specifies that transactions cannot read data that has been modified by other transactions but not yet committed and if the current transaction is reading some data then no other transactions can modify that data until the current transaction completes.

Limitations:
  • Lower Concurrency
  • Phantom Reads
Advantage:
  • Eliminates Dirty Reads
  • Eliminates Lost Updates
  • Eliminates Non-Repeatable Reads
4. Snap Shot

 It specifies that the data accessed by any transaction is consistent and valid for that particular transaction and the data will be same throughout the whole transaction. It implements Row Versioning to isolate data for each transaction i.e. it will keep separate version of each modified row in the transaction in the tempdb database totally dedicated to that transaction. Any update of data in the original row will not affect the current transaction.

Limitations:
  • Low performance due to versioning in tempdb
Advantage:
  • Eliminates Dirty Reads
  • Eliminates Lost Updates
  • Eliminates Non-Repeatable Reads
  • Allows multiple updates by versioning
5. SERIALIZABLE Isolation Level

It is highest level in Isolation levels as a result the concurrency rate is low. But it eliminates all issues related to concurrency like dirty read, non repeatable reads, lost updates and even phantom reads. According to this Isolation Level:
  1. Statements cannot read data if other transactions are performing update operations on the data and is not committed yet.
  2. Also no other transactions can perform any update operations until the current transaction completes its read operations.
  3. And the important point here is that it is performing a Range Lock based on the filters used to get the data from the table i.e. it locks not only the current records but also the new records that are falling under the current filter condition. In simple language, no other transactions can insert new rows that are falling under the current filter condition until the transaction completes.                  
Limitations:
  • Lower Concurrency
Advantage:
  • Eliminates Dirty Reads
  • Eliminates Lost Updates
  • Eliminates Non-Repeatable Reads
  • Eliminates Phantom Reads



Reference
http://www.sqllion.com/2009/07/transaction-isolation-levels-in-sql-server/

Reflection - Load Unreferenced Assemblies at runtime

Reflection

The dictionary meaning of the word ‘Reflection’ is ‘to look back to itself’. This is exactly what is meant by the term reflection in programming world. Reflection is an ability of application to look into the structure of itself. Using the reflection technology, we can retrieve the information about the contents of an assembly (constituting classes and interfaces).


Similarly we can drill down to get the members of these types like fields, methods, and properties. Not only this, but we can also instantiate these types and invoke the methods on these. We can even prepare, compile, and load assemblies at runtime.


Another advantage of  Reflection is it allows you to load assemblies on the fly and treat them as if they were part of your application.Typically this can be used to extend your application after it is released to customers.


For instance we use this feature to add additional reports to customers other than the standard reports that ship with the application, with out having to alter any base app code and with out having to perform any patches. Each of our report file is a .net class, the standard reports are compiled with in the Main assembly and if the customer requests for different sets of reports, we write those class files compile them to an assembly and drop in our app bin folder. Thatz all we need to do, the reflection code in the app will take care of the rest.




To demonstrate this, let's setup a hypothetical situation in which we have an application, and a .NET DLL unreferenced by our application whose types we need to access at runtime. The DLL will be called MyDLL.dll, and the application will be called MyApp.exe. How would we view the types contained inside MyDLL from MyApp at runtime when MyDLL isn't referenced by MyApp? The System.Runtime.Assembly class can be used to access MyDLL in the following manner:


System.Reflection.Assembly myDllAssembly =    System.Reflection.Assembly.LoadFile("%MyDLLPath%\\MyDLL.dll"); 


The myDllAssembly object can now be used to access the types contained inside MyDLL. To access a type contained inside MyDLL, System.Reflection.Assembly possesses a method called GetType(), which can return a System.Type that can be used to access all the members of the type we want to retrieve from inside MyDLL. Note that the System.Reflection.Assembly.GetType() method is not to be confused with the GetType() method possessed by all objects; they are related, but quite different, and we will discuss the other GetType() method later. Back to our example; let's say, there is a type inside MyDLL called MyDLLForm which inherits from System.Windows.Forms.Form and is contained in the namespace MyDLLNamespace. To obtain the System.Type of this, we could do the following:


System.Reflection.Assembly myDllAssembly =    System.Reflection.Assembly.LoadFile("%MyDLLPath%\\MyDLL.dll");
System.Type MyDLLFormType = myDllAssembly.GetType("MyDLLNamespace.MyDLLForm");



MyDLLFormType now holds the System.Type of MyDLLForm. We can now access all the members and contained types inside MyDLLForm from MyDLLFormType. However, using this GetType() method will not create an instance of MyDLLForm. To access a type contained inside MyDLL and create an instance of it, System.Reflection.Assembly possesses another method called CreateInstance(). Say, we wanted to create an instance of MyDLLForm, we could use something like this:


System.Reflection.Assembly myDllAssembly =   System.Reflection.Assembly.LoadFile("%MyDLLPath%\\MyDLL.dll");
Form MyDLLFormInstance = (Form)myDllAssembly.CreateInstance("MyDLLNamespace.MyDLLForm");





MyDLLFormInstance now holds an instance of MyDLLForm (remember that MyDLLForm inherits from Form). To create an instance of MyDLLForm, that method will invoke MyDLLForm's constructor. By way of that overload, CreateInstance is expecting a constructor that takes no arguments, as we only passed it the type name we want to create an instance of. However, let's say there is a constructor we want to use to create an instance of MyDLLForm that takes two arguments, a string and an int. To do that, and for example, to pass it a string of "Hi" and an integer value of 113 (one of my favorite numbers), we could use this:
System.Reflection.Assembly myDllAssembly =
   System.Reflection.Assembly.LoadFile("%MyDLLPath%\\MyDLL.dll");

//the arguments we will pass
object[] argstopass = new object[] { (object)"Hi", (object)113 };

Form MyDLLFormInstance = (Form)myDllAssembly.CreateInstance("MyDLLNamespace.MyDLLForm",
     false, //do not ignore the case
     BindingFlags.CreateInstance, //specifies we want to call a ctor method
     null, //a null binder specifies the default binder will be used (works in most cases)
     argstopass, //the arguments (based on the arguments,
                 //CreateInstance() will decide which ctor to invoke)
     null, //CultureInfo is null so we will use
           //the culture info from the current thread
     null //no activation attributes
     );