Thursday, December 30, 2010

WCF TCP Port Sharing

Check this out. WCF allows you to share the same port among the services.

http://msdn.microsoft.com/en-us/library/ms734772.aspx
http://msdn.microsoft.com/en-us/library/ms731810.aspx

The article below has a diagram that depicts the port sharing:
http://www.codeproject.com/KB/WCF/Port_Sharing__in_WCF.aspx

Configuration:
http://blogs.msdn.com/b/drnick/archive/2006/04/14/configuring-http.aspx

Sunday, November 21, 2010

Open source Zip library

DotNetZip is an open source Zip library which is written in managed code. You may freely use it:

http://dotnetzip.codeplex.com/

Tuesday, October 26, 2010

event VS delegate

Check this out.

http://blog.monstuff.com/archives/000040.html

Tuesday, October 19, 2010

Get the field size in the entity

In the entity framework, the diagram shown in the Visual Studio contains field information of all tables. You may get the field size that stores in the diagram by using the following method:

public static int GetMaxLength(ObjectContext p,
            string tb_name,
            string fld_name)
        {
            if (p == null)
            {
                throw new ArgumentNullException();
            }

            MetadataWorkspace w = p.MetadataWorkspace;
            var items = w.GetItems(DataSpace.CSpace);

           //i.Properties["tb_name"].TypeUsage.Facets["MaxLength"].Value
            var v = items.Where(i => string.Compare(i.Name, tb_name, true) == 0);
            EntityType et = v.First();

            object obj = et.Properties[fld_name].TypeUsage.Facets["MaxLength"].Value;
            if (obj != null)
            {
                string len = obj.ToString();
                if (string.Compare(len, "max", true) == 0)
                {
                    return -1;
                }
                else
                {
                    int max_len = Int32.Parse(len);
                    return max_len;
                }
            }
            else
            {
                return 0;
            }
        }

Linq literals

Check this out if you are passing the string into Where():

http://msdn.microsoft.com/en-us/library/bb399176.aspx

Saturday, October 16, 2010

Efficient way to add new parameter

It is so common that we need to add new parameter to the method during the system development or maintenance. Adding new parameter will become unavoidable when the business requirements changed.

For example, you have a method call Process which takes 2 integer parameters as shown below:

        public int Process(int a, int b)
        {
            int result = a + b;
            return result;
        }

Now, what if you have to add a new integer parameter to this method? Normally, we will just simply add a parameter as we used to do. So, the new method will be look like this:

        public int Process(int a, int b, int c)
        {
            int result = a + b + c;
            return result;
        }

Again, you have to add a new parameter (i.e., fourth parameter) due to the business process changed. OK. I think we need an efficient way to do this.

To avoid adding new parameter to the method (i.e., changing the method signature), we have to pass a struct or a object to the method. To do this,

1. Declare a class call MyParam:

        public class MyParam
        {
            public int a { get; set; }
            public int b { get; set; }
            public int c { get; set; }
        }

2. Change the Process method to take in the MyParam class instead of the 3 parameters:

        public int Process(MyParam p)
        {
            int result = p.a + p.b + p.c;
            return result;
        }

3. If you want to the fourth parameter, you have to add a new property instead of parameter. Also, the caller will no longer require to be modify because the method signature does not change.

The new MyParam class will be look like this:

        public class MyParam
        {
            public int a { get; set; }
            public int b { get; set; }
            public int c { get; set; }
            public int d { get; set; } //<== new parameter.
        }

Of course, the implementation within the Process method must be modify and the caller must assign the value to property 'd' before passing it to the Process method.

Thursday, September 23, 2010

A substitute of switch.. case

Problem: is there anyway to replace the uses of 'switch..case' because I have many 'cases' in the switch statement which is hard to maintain.

Solution: you may try to replace the 'switch..case' with Dictionary + reflection. By using this plug and play design, you will be able to expand your program easily.

For example, you have a class call ProcessSwitches which handles the process request:
    public class ProcessSwitches
{
public string Process(int process_index)
{
string result = string.Empty;

switch (process_index)
{
case 0:
result = this.Cleaning();
break;
case 1:
result = this.Polishing();
break;

//other processes go here...

default:
result = "underdefined";
break;
}

return result;
}

string Cleaning()
{
return "Cleaning process.";
}

string Polishing()
{
return "Polishing process";
}

// many other methods here...
}
Of course, whenever you need to provide a new service, you have to add a new 'case' and a method specifically for that purpose. In case you have a very long list of services, you may not want to see a many hundred lines of cases here.

To overcome this problem, we need to define an interface which will serve the common method call. Then, each service will be converted from method (ie, ProcessSwitches.Cleaning and ProcessSwitch.Polishing) to class individually.
    public interface IProcess
{
string Execute();
}

public class Cleaning : IProcess
{
public string Execute()
{
return "cleaning..";
}
}

public class Drying : IProcess
{
public string Execute()
{
return "drying..";
}
}
After converting the methods to classes, we need to create a registry (or repository) to store the service index and class mapping.
    public class ProcessRegistry : Dictionary
{
public ProcessRegistry()
{
this.Init();
}

void Init()
{
this.Add(0, typeof(Cleaning));
this.Add(0, typeof(Polishing));

//you may add more other process here.
//...
}
}
The final step will be replacing the 'switch..case' by the ProcessRegistry that we have created. Since the ProcessRegistry was inherited from Dictionary class, you may retrieve the class type that you have setup in the ProcessRegistry.Init method.
    public class ProcessSwitchesNew
{
ProcessRegistry registry = new ProcessRegistry();

public string Process(int process_index)
{
string result = string.Empty;
Type type;

// now, you may replace the 'switch..case' with Dictionary class.
// which allows you to provide more services without modifying this method.
if (registry.TryGetValue(process_index, out type))
{
// instantiate the object.
object obj = Activator.CreateInstance(type);
// cast it as IProcess interface.
IProcess process = obj as IProcess;

if (process != null)
{
// execute the process.
result = process.Execute();
}
}

return result;
}
}
Now, what is the benefit you receive from this design?

Benefits:
- You can create and test the service class individually or pass the class development to your team member.

- Easier to increase the number of cases without have the mess around within the 'switch..case' statement. What you need to do is to add a new line in the ProcessRegistry.Init method. Anyone can do it easily.

- The service classes (such as Cleaning and Polishing) can be reuse without have to dismantle the 'switch..case'. Just setup a new registry class and load the necessary class types.

Of course, everything comes in costs. There are disadvantages in this design:
- You might have too many classes.
- The program might run slower due to the use of reflection (ie, Activator) to instantiate the class.

Plug and play design

Problem: we need a design that allows adding new sub-processes easily in the future. It is something like add-on or plug and play concept.

Solution: this problem can be easily resolve in C# by using interface and implement it into various classes.

For example, we need a process that is responsible for cleaning and then drying. In order to achieve the add-on concept, first, we need to define an interface:
public interface IProcess
{
// execute the process.
void Execute();
}
Both the cleaning and drying process must be develop as class instead of method. The classes must implement IProcess interface:
   public class Cleaning : IProcess
{
public void Execute()
{
System.Console.WriteLine("cleaning..");
}
}

public class Drying : IProcess
{
public void Execute()
{
System.Console.WriteLine("drying..");
}
}

Finally, we need to create a class that executes the cleaning and drying process:
   public class RunAllProcess
{
public void Run()
{
// iniatialize the list to store the Type
List< Type> list = new List< Type>();

list.Add(typeof(Cleaning));
list.Add(typeof(Drying));
// you may add more classes here in
// the future with ease...

IProcess process;

foreach (Type item in list)
{
// instantiate the object at runtime.
process = (IProcess)Activator.CreateInstance(item);

// execute the process:
process.Execute();
}
}
}
The reason of using Type list instead of IProcess list is that the object instance will not be created upon adding. It will be instantiate before you execute the process. This is to avoid executing the codes in the class's constructor (if any) which may occupy the memory.

After a while, the user might want to add a new process call polishing. This can be done easily.

Declare a new class:
   public class Polishing : IProcess
{
public void Execute()
{
System.Console.WriteLine("polishing..");
}
}
Then, add a new process:
   public class RunAllProcess
{
public void Run()
{
...
list.Add(typeof(Cleaning));
list.Add(typeof(Drying));
list.Add(typeof(Polishing)); //<==== add the new process here.
...
}
}

Monday, August 30, 2010

Changing constant value at runtime

In C#, you are allowed to set the value for a constant. This can be done by using the "readonly" keyword.

Normally, when we want to declare a constant that is not updateable through out the application by doing the following:

   public const int MAX_DAYS = 30;


In case, your application would like to allow the system administrator changing the MAX_DAYS value to accommodate their business environment, you need a way to do it. This can be done by replacing the "const" keyword with "readonly":

public class MyConstants
(
public readonly int MAX_DAYS;

public MyConstants()
{
MAX_DAYS = {read the value from database OR config file};
}

)

Monday, August 9, 2010

String Comparison Optimization

String myString = String.Intern("VERY LONG STRING #2");

if (Object.ReferenceEquals(myString, "VERY LONG STRING #1"))
{
...
}

else if (Object.ReferenceEquals(myString, "VERY LONG STRING #2"))
{
...
}

else if (Object.ReferenceEquals(myString, "VERY LONG STRING #3"))
{
...
}

...

else

{

...

}

Reference:
http://dotnetfacts.blogspot.com/2008/03/how-to-optimize-strings-comparison.html
http://msdn.microsoft.com/en-us/library/system.string.intern%28vs.71%29.aspx

Wednesday, August 4, 2010

Adding DLL reference automatically

It's quite sad when you are trying to add new reference by using the Add Reference provided in the Visual Studio because it is very slow. To speed up the process, you may have to add the following Macro and run it manually. It will add all your Dll references in one click:

    '4-8-10,lhw
'-add the commonly used dll to the selected project.
' No need to go through the Add Reference screen in VS.
Sub AddGeneralReferences()
Dim proj As EnvDTE.Project
Dim arr As Array = DTE.ActiveSolutionProjects

If Not arr Is Nothing Then
If arr.Length > 0 Then
proj = arr(0)

If Not proj Is Nothing Then
Dim v As VSLangProj.VSProject = proj.Object
Dim r As VSLangProj.References = v.References

If Not r Is Nothing Then
r.Add("System.configuration")
r.Add("System.Drawing")

'not sure why must include the
'full reference to system.web dll.
'Otherwise, COM error will occur.
r.Add("C:\WINDOWS\Microsoft.NET" & _
"\Framework\v2.0.50727\System.Web.dll")

r.Add("System.Web.Services")
End If
End If
End If
End If
End Sub

Thursday, July 29, 2010

Get the current row that fire the command


protected void GridView1_RowCommand(object sender, GridViewCommandEventArgs e)
{
GridViewRow row = (GridViewRow)((Control)e.CommandSource).NamingContainer;

... continue your codes here..
}

Saturday, July 17, 2010

Initialize properties in an object

For example, you have a class which looks like this:

class Customer
{
public string account_code { get; set; }
public string name { get; set; }
public string email { get; set; }
}
This is what we used to do to initialize the properties in a new object:

Customer c1 = new Customer();
c1.account_code = "a001";
c1.name = "ABC Ltd Co";
c1.email = "info@abc.testing.com";
Starts from C# 3.0, you may initialize the properties in a new object instance in a single line of code which looks like this:

Customer c2 = new Customer()
{ account_code = "a001",
name = "ABC Ltd Co",
email = "info@abc.testing.com" };

Sunday, June 20, 2010

Open Data Protocol

Sometimes you might wondering how to develop module by module and then integrate all modules into a single system. Basically, you need a protocol that is design for the integration purpose. This might be something that you are looking for.

Check this out:

http://www.odata.org/developers/protocols/overview

Tuesday, June 8, 2010

Macros for Visual Studio

Run Visual Studio.
  1. Select Tools \ Macros \ Macros IDE.
  2. In the Project Explorer (within the Macros IDE), double click MyMacros \ Module1.
  3. Paste the following codes into the editor.

After that, close the Macros IDE. Now, you may customize the shortcut key to execute the Macro.
  1. Select Tools \ Customize from VS menu.
  2. Click Keyboard button (next to the Close button).
  3. In the "show command containing" field, type "PrintDateTimeSingleLine". This will shortlist the commands that is accessible through VS.
  4. In the "Press shortcut keys" field, press CTRL+0 and click Assign button.
  5. Click OK button to save the customized keyboard settings.
  6. In the coding editor, press CTRL+0 and VS will execute the Macro. So, you don't have to repeatly typing the current date/time for the comments anymore.


Sub PrintDateTime()
If (Not IsNothing(DTE.ActiveDocument)) Then
Dim selection As TextSelection = DTE.ActiveDocument.Selection
selection.Insert(DateTime.Now.ToString("d.MMM.yyyy, ddd @ hh:mm"))
End If
End Sub


Sub PrintDateTimeSingleLine()
If (Not IsNothing(DTE.ActiveDocument)) Then
Dim selection As TextSelection = DTE.ActiveDocument.Selection
selection.Insert("//" & DateTime.Now.ToString("d.MMM.yyyy") & "-lhw-")
End If
End Sub

Sub PrintDateTimeProcHeader()
If (Not IsNothing(DTE.ActiveDocument)) Then
Dim selection As TextSelection = DTE.ActiveDocument.Selection
selection.Insert(DateTime.Now.ToString("d.MMM.yyyy") & "-lhw")
selection.NewLine()
selection.Insert("-")
End If
End Sub


Sub PrintSeparator()
If (Not IsNothing(DTE.ActiveDocument)) Then
Dim selection As TextSelection = DTE.ActiveDocument.Selection
selection.Insert("//-----------------------------------------------------------------------")
End If
End Sub

Sub PrintHeavySeparator()
If (Not IsNothing(DTE.ActiveDocument)) Then
Dim selection As TextSelection = DTE.ActiveDocument.Selection
selection.Insert("//=======================================================================")
End If
End Sub


Sub PrintShortSeparator()
If (Not IsNothing(DTE.ActiveDocument)) Then
Dim selection As TextSelection = DTE.ActiveDocument.Selection
selection.Insert("//-------------------------------------")
End If
End Sub

Sub PrintNotice()
If (Not IsNothing(DTE.ActiveDocument)) Then
Dim selection As TextSelection = DTE.ActiveDocument.Selection
selection.Insert("//<======")
End If
End Sub

Saturday, May 1, 2010

Fullscreen Internet Explorer

To run the Internet Explorer in fullscreen,
   iexplore.exe -k
Below is the C++ code in calling Internet Explorer to show 2 tab pages in fullscreen mode:

CComQIPtr sp = pActiveSite;
(pActiveSite is IOleClientSite *)
CComPtr m_pBrowser;
HRESULT hr = sp->QueryService(IID_IWebBrowserApp, IID_IWebBrowser2,
(void**)&m_pBrowser);
VARIANT_BOOL v = VARIANT_FALSE;
VARIANT_BOOL v1 = VARIANT_TRUE;

m_pBrowser->put_TheaterMode(v1);
m_pBrowser->put_TheaterMode(v);
Reference:
http://www.vistaheads.com/forums/microsoft-public-internetexplorer-general/289892-ie7-fullscreen-toggle-effect-programmatically-similar-like-f11.html

Saturday, April 17, 2010

AsyncOperationManager for WinForm

To run a process in a thread that is other than UI, you may use the following:

1. BackgroundWorker class - allows you to post the progress in integer type only.
2. AsyncOperationManager class - allows you to post any object into the method that is running in the UI context.

If you need to pass the information to be shown in the UI, AsyncOperationManager is much more flexible.

Below is the sample code on using the AsyncOperationManager class.

private void button3_Click(object sender, EventArgs e)
{
AsyncOperation ao
= AsyncOperationManager.CreateOperation(null);

Thread t = new Thread(new
ParameterizedThreadStart(DoRun2));
t.Start(ao);
}

public void DoRun2(object state)
{
AsyncOperation ao = (AsyncOperation)state;

int j;

for (int i = 0; i < 100; i++)
{
j = tl.id;
ao.Post(this.DoProgress2, i);
System.Threading.Thread.Sleep(90);
}

ao.OperationCompleted();
}
void DoProgress2(object state)
{
// you don't have to call label2.Invoke() method because
// ao.Post() will put the context back to the UI
// context automatically.
this.label2.Text = state.ToString();
}

Tuesday, March 2, 2010

Reflection performance

The following is the reference on reflection performance:

http://msdn.microsoft.com/en-us/magazine/cc163759.aspx
http://www.drdobbs.com/windows/184416570

Basically, to speed up the reflection, you should do this:
1. Cache the object instance that you have created and reuse it later.
2. Using Interface or delegate to invoke the method instead of MethodInfo.Invoke.
3. Create the assembly dynamically using Reflection.Emit.

Monday, January 18, 2010

global.asax - rewriting the URL

This is something interesting that you might want to explore in ASP.NET. The question is how to handle the following URL:

http://localhost/myWebsite/beers

Instead, there are a few ways to achieve it. The easiest way is to use the "urlMappings" in the web.config file. But, this is good for the website that does not update frequently.


  <system.web>

    <urlMappings>
      <add url="~/beers" mappedUrl="~/article_list.aspx?id=1111"/>
    </urlMappings>
  </system.web>



If you have a website that requires to publish the contents that stores in the database, then, you might wonder how to achieve the same result. So, the URL mapping feature can't meet the requirement.

Two ways to achieve this:
(1) you may create a class that inherits from IHttpModule OR
(2) add global.asax to the website and then override BeginRequest method.


Sample code


protected void Application_BeginRequest(object sender, EventArgs e)
{
try
{
// get the requested URL.
string s = this.Request.RawUrl.ToString();
// get the current website url including the virtual directory.
string current_website = (String)Application["current_website"];

if (String.IsNullOrEmpty(current_website))
{
current_website = VirtualPathUtility.ToAbsolute("~/");
Application["current_website"] = current_website;
}

// remove the virtual directory. So, only the requested file name will be in the string.
string s2 = s.Replace(current_website, "");

// if the string contains "." (ie, file extension dot)
// or "/" (ie, the folder separator), exit the checking.
if ((s2.Contains("/"))
|| (s2.Contains("."))
)
{
return;
}
else
{
// Now, we need to search for the string in the database that matches the requested url.
// If found the record, we will rewrite the url. The new URL will not reflect in the client browser.
if (s2.CompareTo("beers") == 0)
{
string url = "~/article.aspx?id=1111";
((HttpApplication)sender).Context.RewritePath(url);
}
}
}
catch (Exception ex)
{
// exception handler goes here.

}
}