Sunday, December 26, 2010

Encapsulation: Local change - Local effect principle

One of the central principles of object oriented programming is Encapsulation. Encapsulation states that the implementation details of an object are hidden behind the methods that provide access to that data. But why is encapsulation a good idea? Why bother to do it in the first place? Just stating that it's "good OO design" isn't sufficient justification.

There is one primary justification of encapsulation. It's a principle I call "Local Change - Local Effect". If you change code in one spot, it should only require changes in a small neighborhood surrounding the original change. When used properly, encapsulation allows software to change gradually without requiring bulk changes throughout the system (Change of code in one place requires code change in many places is known as Domino effect).

Encapsulation helps follow this principle by allowing changes in the representation of an object's state. The methods for the object may be affected, but callers of those methods shouldn't be. The effects of the change are localized.

Polymorphism helps by allowing us to add new objects without changing existing code to know about them. You only need to add the new classes and new methods. You shouldn't need to change existing code.

Inheritance helps by providing one place to put common code for many similar objects. Changes to this code can be isolated to the superclass and may require no changes to subclasses in order to make them work.

There are many coding practices that tend to work against the local change/local effect principle. They include:
  • Copy and Paste Code- by making more copies of code, you have more things that need to be changed for any change in design.
  • Public instance variables - by making instance variables public, more people can use them directly and require more changes if you need to change the representation.
  • Manifest types - the type information for variables and parameters often causes domino effect changes. When you change the type that a method accepts, you may have to change its callers and their callers and so forth.
In any software system, the one thing you can count on is change. The local change/local effect principle makes change possible. Without it, as a system gets larger, it becomes more brittle and eventually becomes unmaintainable.
Think about your design principles. If they don't support local change/local effect, you may be building a system that will become too brittle to ever change again.

courtesy: http://www.simberon.com/domino.htm

Monday, October 11, 2010

List of processes running on Remote/Local Computer using C#

ArrayList alist = new ArrayList();

// From remote machine
Process[] processes = Process.GetProcesses("RemoteComputerName"); 

// From local machine
Process[] processes = Process.GetProcesses();    

foreach (Process process in processes)
{
       alist.Add(process.ProcessName);
}

Friday, October 8, 2010

Limitations of COM Interop

Following is the list of some shortcomings:

  • Static/shared members: COM objects are fundamentally different from .Net types. One of the differences is lack of support for static/shared members.
  • Parameterized Constructors: COM types don't allow parameters to be passed into a constructor. This limits the control you have over initialization and the use of overloaded constructors.
  • Inheritance: One of the biggest issues is the limitations COM objects place on the inheritance chain. Members that shadow members in a base class aren't recognizable, and therefore, aren't callable or usable in real sense.
  • Portability: Operating Systems other than Windows don't have registry. Reliance on Windows registry limits the number of environments a .Net application can be ported to.

Why Visual Studio hangs

Every once in a while, VS seems to take forever to display a screen to the point that it seems to hang. Most of the time, it hangs, while accessing Fonts and Colors page in Tools/Options dialog. The issue is not that there is some weird code that executes very slowly. It happens that this page is implemented using .NET components. Now the majority of VS is built with native code and during most of its execution,, the CLR is never loaded. However, when the user accesses one of these features, the CLR must be loaded, before we can begin executing the relevant IL. It is this process that is time-consuming and annoying to the user. There are two problems for the users here: first, there is no feedback during loading of the CLR; second: the problem can occur multiple times within a single session of VS.


I am trying to figure out the reason for this second issue. Let me know, if any of you knows.

Optional Parameter issue with COM and C#/VB

As we all know, C# doesn't support optional parameters(till framework 3.5) whereas VB does.In the same way, COM components don't support parameter overloading, so for each value in a parameter list, we've got to pass in something, even if it does nothing. Moreover, COM parameters are always passes by reference, which means we can't pass NULL as a value.


In VB 2005, this is not really as issue because it supports optional parameters and we can just leave them out. But C# doesn't support this, so one have to create object variables and pass them in.


See following code sample:
using Microsoft.Office.Core;
using Microsoft.Office.Interop.Excel;  // Must have office installed
Application NewExcelApp = new Application;
NewExcelApp.Worksheets.Add();       // This will not compile


So, as a workaround, the Type.Missing field can be used and this field can be passed in with the C# code and the application will work as expected. 


Check it in below code snippet:


using Microsoft.Office.Core;
using Microsoft.Office.Interop.Excel;  // Must have office installed
private Object OptionalParamHandler = Type.Missing;
Application NewExcelApp = new Application;
NewExcelApp.Worksheets.Add(OptionalParamHandler ,OptionalParamHandler ,OptionalParamHandler ,OptionalParamHandler ); 

This approach allows your code to work in C# :)









Wednesday, September 15, 2010

Making assembly visible to a COM component

Following steps are necessary to make an assembly visible to a COM component:

  • Set the Register for COM option under the build configuration
  • Set the ComVisible attribute to true for each class you want exposed
  • Set the ComVisible attribute to false for any class members you want hidden
  • Set the ComVisible attribute to true for any class members that you want visible

Friday, September 10, 2010

Which is fastest While, Do-While, Foreach

Foreach will be faster as it usually maintain no explicit counter, like while and do-while. Foreach essentially say "do this to everything in this set", rather than "do this x times". This will potentially avoid off-by-one errors and make code simpler to read.

Using frequently build assembly in another applications (.Net)

Assume that you are creating a strong named MyAssembly that will be used in several applications. The assembly will be rebuilt frequently during the development cycle. But one must ensure that every time MyAssembly is rebuilt, it works properly with all applications that use it. So, in order to obtain this, we are required to configure the computer on which we develop the assembly such that each application uses the latest build of MyAssembly. To accomplish the above task, take the following action:


  • To point to the build output directory for the strong named assembly, create a DEVPATH environment variable
  • Add the following element to the machine configuration file: <developmentMode developerInstallation="true">. This element tells the CLR to use DEVPATH to locate assembly.

What is a serviced component?

A services component is a .Net component that uses component services of COM+, such as object pooling, transaction management etc. It executes within the managed execution environment of the .Net framework and shares its context with a COM+ application. It enables context sharing between COM+ and .Net framework classes. A serviced component is creates by defining  class that directly or indirectly derives from the ServicesComponent class. It utilizes COM+ services by using attributes of the System.EnterpriseServices namespace. A serviced component should be registered before it can access the component services of COM+. The following three types of registrations are used to register a serviced component:

  • Manual registration: The .Net Framework Service Installation (Regsvcs.exe) tool is used to manually register an assembly containing a serviced component. Manual registration is used for design-time testing to find out the error types that may occur at runtime.
  • Dynamic registration: In dynamic registration, as assembly with a serviced component is copied into the COM+ application's directory. Dynamic registration is used only when a serviced component is created by a managed client.
  • Programmatic registration: Programmatic registration is used to register as assembly containing a serviced component programmatically by creating as instance of the RegistrationHelper class.

Tuesday, September 7, 2010

Covariance and Contravariance feature of .NET 4.0

Hi,
I'll consider below class hierarchy throughout this explanation:

class Account { }
class Savings : Account { }
class Current : Account { }
Now lets begin with Example 1:
class Program
{
delegate T MyDel<T>();
static void Main(string[] args)
{
MyDel<Savings> objSavings = () => new Savings();
MyDel<Account> objAccount = objSavings;
}
}
The code shown in Example 1 will not work in versions prior to 4.0. But if you change generic parameter T to OUT T in 4.0, then this assignment compatibility work via CoVariance. Now check this 4.0 code in Example 2:
class Program
{
delegate T MyDel<out T>();
static void Main(string[] args)
{
MyDel<Savings> objSavings = () => new Savings();
MyDel<Account> objAccount = objSavings;
}
}
The only change in Example 2 is additional OUT keyword.
Now lets move to ContraVariance:
ContraVariance supports the opposite direction of assignment with IN keyword as shown in Example 3:
class Program
{
delegate T MyDel<in T>(T t);
static void Main(string[] args)
{
MyDel<Account> objAccount = (account) => Console.WriteLine(account); MyDel<Savings> objSavings = objAccount;
}
}



These variance come into picture with Generics, Delegates, Interfaces and Collections.

Certain authenticated sharepoint users get "Access Denied" error

When we add our Active Directory groups into Sharepoint site groups, some of the group members receives Access Denied message. This is the problem faced in sharepoint 2007 and doesn't resolve even  individual members of the group are added. So, to get rid of it, just try through following steps:

  • add users in DomainName/UserName format, instead of using just UserName. Avoid adding AD groups directly
  • if you have hosted your site on port 80, and using different name apart from machine name as http://ABC, in this case don't forget to make a entry of your site in Alternate Access Path, under operations tab in central administration.
Hope, this post is helpful to you :)

Friday, September 3, 2010

Lazy initialization – Lazy (.NET 4.0)

With lazy initialization, the memory for an object is not allocated until it is needed. This mainly used to improve performance, reduces unnecessary computations and also reduce memory requirements. This can be useful in following scenarios:

  1. When creation of object is expensive and we want to deferred the creation until it is used.
  2. When you have an object that is expensive to create, and the program might not use it. For example, assume that you have in memory a Customer object that has an Orders property that contains a large array of Order objects that, to be initialized, requires a database connection. If the user never asks to display the Orders or use the data in a computation, then there is no reason to use system memory or computing cycles to create it. By using Lazy<Orders> to declare the Orders object for lazy initialization, you can avoid wasting system resources when the object is not used.
Example:



class MyClass
{
    public string MyData { get; set; }

    public MyClass(string message)
    {
        this.MyData = message;
        Console.WriteLine("  ***  MyClass constructed [{0}]", message);
    }
}



We can declare and use this by creating a lambda expression to pass in our string parameter:
Lazy<MyClass> classInstance = new Lazy<MyClass>(
        () => new MyClass("The message")
    );
We then have access to the IsValueCreated property, which tells us whether or not the instance has been created, as well as the Value property, which will construct and return our actual instance on demand.
Here’s an example showing a complete program using the MyClass above, demonstrating the usage of Lazy<T>:
class Program
{
    static void Main(string[] args)
    {        
        MyClass instance1 = new MyClass("instance1");
        Lazy<MyClass> instance2 = new Lazy<MyClass>(() => new MyClass("instance2"));
        Console.WriteLine("Instances declared");
        Console.WriteLine();
        Console.WriteLine("instance2's MyClass initialized:  {0}", instance2.IsValueCreated);
        Console.WriteLine(); 

        Console.WriteLine("instance1.MyData: {0}", instance1.MyData);
        Console.WriteLine("instance2.MyData: {0}", instance2.Value.MyData);
        Console.WriteLine();
        Console.WriteLine("instance2's MyClass initialized:  {0}", instance2.IsValueCreated);
        Console.ReadKey();
    }
}
The above program, when run, prints out:
***  MyClass constructed [instance1]
Instances declared

instance2's MyClass initialized:  False

instance1.MyData: instance1
  ***  MyClass constructed [instance2]
instance2.MyData: instance2

instance2's MyClass initialized:  True
So, this LAZY type automatically delayed our construction until the first type we accessed it (instance2.Value.MyData).

Use of .NET Framework 4 Client Profile

The .NET Framework 4 Client Profile is a subset of the .NET Framework 4 that is created specifically for client applications(including WinForm, WPF, WCF, and ClickOnce). This enables faster deployment experience by having smaller download sizes and quicker install times. An application that targets the .NET Framework 4 Client Profile has a smaller redistribution package that installs the minimum set of client assemblies on the user's computer, without requiring the full version of the .NET Framework 4 to be present.



When you deploy an application that targets the .NET Framework 4 Client Profile, you only need to deploy the .NET Framework 4 Client Profile. If you are deploying using ClickOnce, you can select the .NET Framework 4 Client Profile as the .NET Framework Launch Condition. 

If you deploy the .NET Framework 4 Client Profile and your application targets the .NET Framework 4, the user will be prompted to install the .NET Framework 4 when he or she tries to run your application.
Source: MSDN

Running applications of earlier versions of .Net framework on framework 4.0

The .NET Framework 4 does not automatically use its version of the CLR to run applications that are built with earlier versions. To run older applications with .NET Framework 4, one must compile their application with the target .NET Framework version specified in the properties for your project in VS, or you can specify the supported runtime with the <supportedRuntime> Element in an App.Config

Sunday, August 29, 2010

Named Parameter feature of C#.Net 4.0

Lets assume, your constructor definition looks like this:
public Employee(string firstName, string lastName, DateTime dateOfBirth)

In that case, you have no other option in C# 3.0 other than to invoke the constructor like this:
Employee employee = new Employee ("Shweta", "Jain", new DateTime(1990, 1, 1));


So, now in this case, it is not clear about what is being assigned in the constructor (e.g., that third DateTime parameter might be date of birth, might be date hired, who knows).  
In C# 4.0, you can invoke the constructor like this:

Employee employee = new Employee(firstName: "Shweta", lastName: "Jain", dateOfBirth: new DateTime(1990, 1, 1));
This expresses the intent clearly and makes the code more understandable.