<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-7462882</id><updated>2011-09-28T21:57:52.046-04:00</updated><category term='C#'/><category term='C++'/><category term='Visual Studio'/><category term='Life'/><category term='TDD'/><category term='SQL'/><category term='CSS'/><category term='Enterprise Library'/><category term='Asp.Net'/><category term='.Net'/><category term='Tools'/><category term='Mock'/><category term='Asp.Net MVC'/><category term='Book'/><category term='Windows'/><category term='algorithm'/><category term='JavaScript'/><category term='Error Handling'/><category term='GMap'/><category term='Programming'/><category term='OSS'/><title type='text'>GIS Research</title><subtitle type='html'>Some C++, C#, .Net, windows service, GIS thoughts posted by me.


有度量去容忍那些不能改变的事，有勇气去改变那些可能改变的事，有智慧去区分上述两件事。</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://gisresearch.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7462882/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://gisresearch.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><link rel='next' type='application/atom+xml' href='http://www.blogger.com/feeds/7462882/posts/default?start-index=101&amp;max-results=100'/><author><name>J.W.</name><uri>http://www.blogger.com/profile/09241601264454722977</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://farm3.static.flickr.com/2116/1856041089_20ef060d43_o.jpg'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>207</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-7462882.post-5355558690497302200</id><published>2011-01-26T22:13:00.001-05:00</published><updated>2011-01-27T21:49:28.027-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Tools'/><title type='text'>Use Git on Windows (Add files into github)</title><content type='html'>&lt;p&gt;I want to start to use Git to store some practice projects on &lt;a href="https://github.com/"&gt;GitHub&lt;/a&gt;, I used to use Mercurial to store it on &lt;a href="http://code.google.com/hosting/"&gt;google code.&lt;/a&gt;&amp;#160; I enjoyed using Mercurial Tool, and google code has more generous storage and I think I will still use it as the primary hobby code storage. I use TFS at my workplace. The best tutorial I found online is &lt;a href="http://www.lostechies.com/blogs/jason_meridth/archive/2009/06/01/git-for-windows-developers-git-series-part-1.aspx"&gt;this three part series&lt;/a&gt;, but here is my own summary for my reference in the future.&lt;/p&gt;  &lt;p&gt;&lt;font size="4"&gt;1.&lt;/font&gt; Go To &lt;a href="http://code.google.com/p/msysgit/"&gt;msysgit&lt;/a&gt;, and download the installation file, if you are not sure which one to download, then I will suggest using the one which has the most download count.&lt;/p&gt;  &lt;p&gt;&lt;font size="4"&gt;2.&lt;/font&gt; After installing, start GitBash (which runs inside &lt;a href="http://www.mingw.org/"&gt;minGW&lt;/a&gt; environment), and the first thing which needs to be done is to create SSH keys with the following command&lt;strong&gt; “ssh-keygen –C &lt;/strong&gt;&lt;a href="mailto:%E2%80%98your@mail.com%E2%80%99"&gt;&lt;strong&gt;‘your@mail.com’&lt;/strong&gt;&lt;/a&gt;&lt;strong&gt; –t rsa”&lt;/strong&gt;&amp;#160; .&amp;#160; This will generate two keys inside the .ssh directory , and you need paste the public key into your SSH Public Keys inside your account.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;a href="http://lh5.ggpht.com/_skGtCbVaJ2o/TUDtxRoXMJI/AAAAAAAABvQ/_l4mv8hgR2w/s1600-h/image%5B2%5D.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; margin: ; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://lh4.ggpht.com/_skGtCbVaJ2o/TUDtx7-8uFI/AAAAAAAABvU/tputUeSV45g/image_thumb.png?imgmax=800" width="244" height="206" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&lt;em&gt;If these files are already generated on the other computer, they can be copied over instead of being regenerated.&lt;/em&gt;&lt;/p&gt;  &lt;p&gt;&lt;font size="4"&gt;3.&lt;/font&gt; Do some initial configuration, use git config – - globla , I only configured three variables: name, emailaddress, and .gitingore file. Those commands are &lt;/p&gt; &lt;font style="background-color: #a5a5a5"&gt;   &lt;p&gt;$ &lt;strong&gt;git config&lt;/strong&gt; --global user.name &amp;quot;Tekkub&amp;quot; &lt;/p&gt;    &lt;p&gt;$ &lt;strong&gt;git config&lt;/strong&gt; --global user.email &lt;a href="mailto:tekkub@gmail.com"&gt;tekkub@gmail.com&lt;/a&gt;&lt;/p&gt;    &lt;p&gt;$ &lt;strong&gt;git config&lt;/strong&gt; --global core.excludesfile &lt;a href="mailto:tekkub@gmail.com"&gt;tekkub@gmail.com&lt;/a&gt;&lt;/p&gt; &lt;/font&gt;  &lt;p&gt;There are a lot of other commands, but those are enough to help me started.&lt;/p&gt;  &lt;p&gt;&lt;font size="4"&gt;4.&lt;/font&gt; Now, you can navigate to the folder you want to add to the github. use &lt;a href="http://help.github.com/creating-a-repo/"&gt;the following commands reference on this page&lt;/a&gt;.&lt;/p&gt; &lt;font style="background-color: #a5a5a5"&gt;   &lt;p&gt;&lt;strong&gt;$git init&lt;/strong&gt;&amp;#160; [This will initialize the direcotry]&lt;/p&gt;    &lt;p&gt;&lt;strong&gt;$git add. &lt;/strong&gt;[This will add the the files under the current folder]&lt;/p&gt;    &lt;p&gt;&lt;strong&gt;$git commit –m ‘commit message’&lt;/strong&gt; [This will commit the changes]&lt;/p&gt;    &lt;p&gt;&lt;strong&gt;$git remote add origin&lt;/strong&gt; ******(replace the *** with the url on github)&lt;/p&gt;    &lt;p&gt;&lt;strong&gt;$git push origin master&lt;/strong&gt;&lt;/p&gt;    &lt;p&gt;&lt;font style="background-color: #ffffff"&gt;&lt;/font&gt;&lt;/p&gt; &lt;/font&gt;  &lt;pre&gt;&amp;#160;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&amp;#160;&lt;/pre&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7462882-5355558690497302200?l=gisresearch.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gisresearch.blogspot.com/feeds/5355558690497302200/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7462882&amp;postID=5355558690497302200' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7462882/posts/default/5355558690497302200'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7462882/posts/default/5355558690497302200'/><link rel='alternate' type='text/html' href='http://gisresearch.blogspot.com/2011/01/use-git-on-windows.html' title='Use Git on Windows (Add files into github)'/><author><name>J.W.</name><uri>http://www.blogger.com/profile/09241601264454722977</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://farm3.static.flickr.com/2116/1856041089_20ef060d43_o.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh4.ggpht.com/_skGtCbVaJ2o/TUDtx7-8uFI/AAAAAAAABvU/tputUeSV45g/s72-c/image_thumb.png?imgmax=800' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7462882.post-4388007360414300543</id><published>2010-12-30T13:03:00.001-05:00</published><updated>2011-01-11T14:14:02.796-05:00</updated><title type='text'>Visual Studio Shortcut</title><content type='html'>&lt;ol&gt; &lt;li&gt;Ctrl + .&amp;nbsp; Generate Method Stub. &lt;/li&gt; &lt;li&gt;Alt + U Go To File. &lt;a href="http://www.usysware.com/dpack/"&gt;DPack&lt;/a&gt;  &lt;/li&gt; &lt;li&gt;Alt + G Go To Member. &lt;a href="http://www.usysware.com/dpack/"&gt;DPack&lt;/a&gt; &lt;/li&gt;&lt;/ol&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7462882-4388007360414300543?l=gisresearch.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gisresearch.blogspot.com/feeds/4388007360414300543/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7462882&amp;postID=4388007360414300543' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7462882/posts/default/4388007360414300543'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7462882/posts/default/4388007360414300543'/><link rel='alternate' type='text/html' href='http://gisresearch.blogspot.com/2010/12/visual-studio-shortcut.html' title='Visual Studio Shortcut'/><author><name>J.W.</name><uri>http://www.blogger.com/profile/09241601264454722977</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://farm3.static.flickr.com/2116/1856041089_20ef060d43_o.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7462882.post-5082329639506412586</id><published>2010-12-30T11:52:00.001-05:00</published><updated>2011-01-13T11:02:57.917-05:00</updated><title type='text'>Vim Shortcuts</title><content type='html'>&lt;ol&gt; &lt;li&gt;&lt;a href="http://stackoverflow.com/questions/1620018/vi-editor-copy-all-the-lines-to-clipboard"&gt;yank all lines to clipboard&lt;/a&gt;&lt;pre&gt;&lt;code&gt;:%y+&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://www.tuxfiles.org/linuxhelp/vimcheat.html"&gt;Copy multiple line&lt;/a&gt;&lt;pre&gt;&lt;code&gt;V (Start highlight) + normal move keys to select + y &lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://www.tuxfiles.org/linuxhelp/vimcheat.html#replace"&gt;Replace word in file &lt;/a&gt;&lt;pre&gt;&lt;code&gt; :r(use % to replace whole file)s/foo/bar/a &lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;&lt;br /&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://hurley.wordpress.com/2007/06/13/vim-tip-comment-out-multiple-lines/"&gt;Replace word in file &lt;/a&gt;&lt;pre&gt;&lt;code&gt; CTRL-V (CTRL-G is CTLV-V is used for paste on windows)+Select + I(UpperCase)+ comment+ESC &lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;&lt;br /&gt;&lt;br /&gt;&lt;/ol&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7462882-5082329639506412586?l=gisresearch.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gisresearch.blogspot.com/feeds/5082329639506412586/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7462882&amp;postID=5082329639506412586' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7462882/posts/default/5082329639506412586'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7462882/posts/default/5082329639506412586'/><link rel='alternate' type='text/html' href='http://gisresearch.blogspot.com/2010/12/vim-shortcuts.html' title='Vim Shortcuts'/><author><name>J.W.</name><uri>http://www.blogger.com/profile/09241601264454722977</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://farm3.static.flickr.com/2116/1856041089_20ef060d43_o.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7462882.post-2092738209661441397</id><published>2009-08-10T20:41:00.001-04:00</published><updated>2009-08-10T20:41:33.977-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Asp.Net MVC'/><category scheme='http://www.blogger.com/atom/ns#' term='Book'/><title type='text'>Pro ASP.NET MVC Framework</title><content type='html'>&lt;p&gt;I just finished reading &lt;a href="http://www.amazon.com/Pro-ASP-NET-Framework-Steven-Sanderson/dp/1430210079/ref=ntt_at_ep_dpi_1"&gt;Pro ASP.NET MVC Framework&lt;/a&gt; and really enjoyed reading this book. I have briefly read other asp.net mvc books such as &lt;a href="http://www.amazon.com/Professional-ASP-NET-MVC-Wrox-Programmer/dp/0470384611/ref=sr_1_3?ie=UTF8&amp;amp;qid=1249950795&amp;amp;sr=8-3"&gt;Professional ASP.NET MVC 1.0&lt;/a&gt; and &lt;a href="http://www.amazon.com/ASP-NET-MVC-Action-Jeffrey-Palermo/dp/1933988622/ref=sr_1_1?ie=UTF8&amp;amp;qid=1249950795&amp;amp;sr=8-1"&gt;ASP.NET MVC in Action&lt;/a&gt;, but enjoyed reading this book mostly. &lt;/p&gt;  &lt;p&gt;&lt;a href="http://www.amazon.com/Pro-ASP-NET-Framework-Steven-Sanderson/dp/1430210079/ref=ntt_at_ep_dpi_1"&gt;Pro ASP.NET MVC Framework&lt;/a&gt; takes a very practical approach on how to build the applications with asp.net mvc. The book didn’t go through every asp.net mvc feature, but it takes you to a natural direction on what kind of feature you will need on a particular step of building the application. &lt;a href="http://www.amazon.com/Professional-ASP-NET-MVC-Wrox-Programmer/dp/0470384611/ref=sr_1_3?ie=UTF8&amp;amp;qid=1249950795&amp;amp;sr=8-3"&gt;Professional ASP.NET MVC 1.0&lt;/a&gt; is more about what the asp.net framework contains regarding building the application, while &lt;a href="http://www.amazon.com/Pro-ASP-NET-Framework-Steven-Sanderson/dp/1430210079/ref=ntt_at_ep_dpi_1"&gt;Pro ASP.NET MVC Framework&lt;/a&gt; is about how you should utilize certain feature when building application.&lt;/p&gt;  &lt;p&gt;This book also touches other open source frameworks such as the Castle Project when building the IOC container for the controller, and jQuery when building the Ajax part. Even those are not built-in part of the asp.net mvc frameowork, they are essentially building blocks in normal asp.net mvc application building.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7462882-2092738209661441397?l=gisresearch.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gisresearch.blogspot.com/feeds/2092738209661441397/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7462882&amp;postID=2092738209661441397' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7462882/posts/default/2092738209661441397'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7462882/posts/default/2092738209661441397'/><link rel='alternate' type='text/html' href='http://gisresearch.blogspot.com/2009/08/pro-aspnet-mvc-framework.html' title='Pro ASP.NET MVC Framework'/><author><name>J.W.</name><uri>http://www.blogger.com/profile/09241601264454722977</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://farm3.static.flickr.com/2116/1856041089_20ef060d43_o.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7462882.post-4844627068735056117</id><published>2009-07-06T15:49:00.001-04:00</published><updated>2009-07-06T15:49:35.915-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Error Handling'/><category scheme='http://www.blogger.com/atom/ns#' term='Asp.Net MVC'/><title type='text'>Error handling issue in Asp.net mvc contact manage example.</title><content type='html'>&lt;p&gt;I am going through the codes in the &lt;a href="http://www.asp.net/Learn/mvc/"&gt;asp.net mvc contact manger&lt;/a&gt; example. There is one piece of code which will mislead when some error happens.&lt;/p&gt;  &lt;p&gt;In the controller, we have this code. &lt;/p&gt;  &lt;pre class="brush: csharp;"&gt;      [AcceptVerbs(HttpVerbs.Post)]&lt;br /&gt;        public ActionResult Create(int groupId, [Bind(Exclude = &amp;quot;Id&amp;quot;)] Contact contactToCreate)&lt;br /&gt;        {&lt;br /&gt;            if (_service.CreateContact(groupId, contactToCreate))&lt;br /&gt;                return RedirectToAction(&amp;quot;Index&amp;quot;, new {id=groupId});&lt;br /&gt;            AddGroupsToViewData(groupId);           &lt;br /&gt;            return View(&amp;quot;Create&amp;quot;);&lt;br /&gt;        }&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;And then in service class, it has this piece of code.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: csharp;"&gt;   public class ContactManagerService : IContactManagerService&lt;br /&gt;    {&lt;br /&gt;        private IValidationDictionary _validationDictionary;&lt;br /&gt;        private IContactManagerRepository _repository;&lt;br /&gt;&lt;br /&gt;        #region IContactManagerService Members&lt;br /&gt;&lt;br /&gt;        public bool CreateContact(int groupId, Contact contactToCreate)&lt;br /&gt;        {&lt;br /&gt;            // Validation logic&lt;br /&gt;            if (!ValidateContact(contactToCreate))&lt;br /&gt;                return false;&lt;br /&gt;&lt;br /&gt;            // Database logic&lt;br /&gt;            try&lt;br /&gt;            {&lt;br /&gt;                _repository.CreateContact(groupId, contactToCreate);&lt;br /&gt;            }&lt;br /&gt;            catch&lt;br /&gt;            {&lt;br /&gt;                return false;&lt;br /&gt;            }&lt;br /&gt;            return true;&lt;br /&gt;        }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;Here is the problem, if the _repository.CreateContact(groupId, contactToCreate) throws out some error, the error is silently eaten by the function, and the user will have no idea what had happened. I think it will make much more sense to re-throw this error and take the user to some error page and give the user more information on what’s going on.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: csharp;"&gt;   public class ContactManagerService : IContactManagerService&lt;br /&gt;    {&lt;br /&gt;        private IValidationDictionary _validationDictionary;&lt;br /&gt;        private IContactManagerRepository _repository;&lt;br /&gt;&lt;br /&gt;        #region IContactManagerService Members&lt;br /&gt;&lt;br /&gt;        public bool CreateContact(int groupId, Contact contactToCreate)&lt;br /&gt;        {&lt;br /&gt;            // Validation logic&lt;br /&gt;            if (!ValidateContact(contactToCreate))&lt;br /&gt;                return false;&lt;br /&gt;&lt;br /&gt;            // Database logic&lt;br /&gt;            try&lt;br /&gt;            {&lt;br /&gt;                _repository.CreateContact(groupId, contactToCreate);&lt;br /&gt;            }&lt;br /&gt;            catch&lt;br /&gt;            {&lt;br /&gt;                throw;&lt;br /&gt;            }&lt;br /&gt;            finally&lt;br /&gt;            {&lt;br /&gt;                _repository.Dispose();&lt;br /&gt;            }&lt;br /&gt;            return true;&lt;br /&gt;        }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7462882-4844627068735056117?l=gisresearch.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gisresearch.blogspot.com/feeds/4844627068735056117/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7462882&amp;postID=4844627068735056117' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7462882/posts/default/4844627068735056117'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7462882/posts/default/4844627068735056117'/><link rel='alternate' type='text/html' href='http://gisresearch.blogspot.com/2009/07/error-handling-issue-in-aspnet-mvc.html' title='Error handling issue in Asp.net mvc contact manage example.'/><author><name>J.W.</name><uri>http://www.blogger.com/profile/09241601264454722977</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://farm3.static.flickr.com/2116/1856041089_20ef060d43_o.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7462882.post-6374656995825201990</id><published>2009-07-02T21:52:00.001-04:00</published><updated>2010-02-03T20:03:16.722-05:00</updated><title type='text'>A circular dependency in Asp.Net mvc contact manager example</title><content type='html'>&lt;p&gt;I wrote a &lt;a href="http://gisresearch.blogspot.com/2009/06/learn-aspnet-mvc-through-contactmanager.html"&gt;post&lt;/a&gt; about my understanding of &lt;a href="http://www.asp.net/mvc/learn/"&gt;asp.net mvc contact manager example&lt;/a&gt;, this is a very good example to&amp;#160; demonstrate how to separate your code into different parts of application. Particularly, the example introduced a service layer IContactManagerService to wrapper the repository and validation logic.&amp;#160; The controller doesn’t talk to the repository layer directly, instead , the controller talks to service layer. All in fine unless you try to use some dependency injection framework such as &lt;a href="http://ninject.org/"&gt;NInject&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;Here is the problem, the controller constructor takes IContactManagerService as a parameter. &lt;/p&gt;  &lt;pre class="brush: csharp;"&gt;    public class ContactController : Controller&lt;br /&gt;    {&lt;br /&gt;        private IContactManagerService _service;&lt;br /&gt;&lt;br /&gt;        public ContactController()&lt;br /&gt;        {&lt;br /&gt;            _service = new ContactManagerService(new ModelStateWrapper(this.ModelState));&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        public ContactController(IContactManagerService service)&lt;br /&gt;        {&lt;br /&gt;            _service = service;&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;   }&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;The ContactManagerService needs take IValidationDictionary as a parameter, however, the implementation of IValidationDictionary ModelStateWrapper needs to take a ModelStateDictionary, and this ModelStateDictionary needs to be the ModalState object of the controller, so it introduces a dependency on the controller. &lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: csharp;"&gt;&lt;br /&gt;   public class ModelStateWrapper : IValidationDictionary&lt;br /&gt;    {&lt;br /&gt;        private ModelStateDictionary _modelState;&lt;br /&gt;&lt;br /&gt;        public ModelStateWrapper(ModelStateDictionary modelState)&lt;br /&gt;        {&lt;br /&gt;            _modelState = modelState;&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        public void AddError(string key, string errorMessage)&lt;br /&gt;        {&lt;br /&gt;            _modelState.AddModelError(key, errorMessage);&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        public bool IsValid&lt;br /&gt;        {&lt;br /&gt;            get { return _modelState.IsValid; }&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;Everything is fine until you try to use an injection framework to create the controller, then it will complains the circular dependency.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;a href="http://lh6.ggpht.com/_skGtCbVaJ2o/S2ocfsbVElI/AAAAAAAABgU/BTXw4nrSgeU/s1600-h/image%5B3%5D.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://lh5.ggpht.com/_skGtCbVaJ2o/S2ocgKiG6HI/AAAAAAAABgY/6B9aTP23rS0/image_thumb%5B1%5D.png?imgmax=800" width="581" height="259" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7462882-6374656995825201990?l=gisresearch.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gisresearch.blogspot.com/feeds/6374656995825201990/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7462882&amp;postID=6374656995825201990' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7462882/posts/default/6374656995825201990'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7462882/posts/default/6374656995825201990'/><link rel='alternate' type='text/html' href='http://gisresearch.blogspot.com/2009/07/circular-dependency-in-aspnet-mvc.html' title='A circular dependency in Asp.Net mvc contact manager example'/><author><name>J.W.</name><uri>http://www.blogger.com/profile/09241601264454722977</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://farm3.static.flickr.com/2116/1856041089_20ef060d43_o.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh5.ggpht.com/_skGtCbVaJ2o/S2ocgKiG6HI/AAAAAAAABgY/6B9aTP23rS0/s72-c/image_thumb%5B1%5D.png?imgmax=800' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7462882.post-8068654535726319242</id><published>2009-06-20T14:05:00.001-04:00</published><updated>2009-06-28T16:15:48.713-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='CSS'/><title type='text'>CSS positioning</title><content type='html'>&lt;p&gt;The css style is easier to understand compare to the css positioning.&amp;#160; The css positioning has four values: &lt;/p&gt;  &lt;p&gt;&lt;strike&gt;static&lt;/strike&gt; | relative | absolute | fixed&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Elements that don't use any positioning methods are called static. This is the normal case.The values &lt;tt&gt;absolute&lt;/tt&gt; and &lt;tt&gt;fixed&lt;/tt&gt; imply that the element must be a block. The value of the display property is &lt;strong&gt;&lt;font color="#ff0000"&gt;ignored&lt;/font&gt;&lt;/strong&gt; in this case. Elements that are &lt;font color="#ff0000"&gt;&lt;strong&gt;not &lt;tt&gt;static&lt;/tt&gt;&lt;/strong&gt;&lt;/font&gt; make use of the four positioning properties: top, right, bottom, and left. In other word, if the elements are static, those positioning properties don’t make sense here. &lt;/li&gt;    &lt;li&gt;Containing block      &lt;ul&gt;       &lt;li&gt;The containing block for a &lt;strong&gt;fixed&lt;/strong&gt; positioned element is always the viewport.The parent, or even any other positioned elements, has &lt;strong&gt;&lt;em&gt;&lt;font color="#0000ff"&gt;no&lt;/font&gt;&lt;/em&gt;&lt;/strong&gt; influence on the position of an element with &lt;tt&gt;position: fixed&lt;/tt&gt;. &lt;/li&gt;        &lt;li&gt;&lt;strong&gt;Relatively positioned elements&lt;/strong&gt;, like &lt;strong&gt;normal static elements&lt;/strong&gt;, don't have a &lt;strong&gt;containing block&lt;/strong&gt;. The positioning properties bottom, left, top, and right move the element up, right, down, or left from its &lt;strong&gt;&lt;font color="#ff0000"&gt;normal&lt;/font&gt;&lt;/strong&gt; position. &lt;strong&gt;Fixed elements&lt;/strong&gt; stay fixed to the window. If the window has a scroll bar, the fixed elements do &lt;strong&gt;not&lt;/strong&gt; move with the scroll bar. &lt;strong&gt;Absolutely positioned elements&lt;/strong&gt;, even if they are initially placed relative to the window, move along with the scroll bar. &lt;/li&gt;        &lt;li&gt;Relative positioning: However, the typical use of &lt;strong&gt;relative positioning&lt;/strong&gt; is to position elements away from their &lt;strong&gt;normal&lt;/strong&gt; position without influencing the position of other elements. There &lt;strong&gt;aren't many&lt;/strong&gt; reasons for doing that in a style sheet, and the main reason relative positioning exists at all is to provide a way for scripts to animate the text – to make it &amp;quot;explode&amp;quot; when a page is unloaded or make it slowly move into place when the page is loaded. &lt;/li&gt;        &lt;li&gt;The &lt;strong&gt;containing block&lt;/strong&gt; for a &lt;strong&gt;fixed element&lt;/strong&gt; is thus always the viewport, we need set width, either the left or right, and the top or bottom. &lt;/li&gt;        &lt;li&gt;There are two major ways in which &lt;strong&gt;absolute positioning can be used&lt;/strong&gt;. One is to have a few small absolutely positioned elements in an otherwise normal document; for example, to put a logo in a corner. The other way is to create &amp;quot;areas&amp;quot; for parts of the document, much like the last example for fixed positioning in the previous section. The difference is that the size of the window isn't taken into account. Although most browsers will use the width of the window for the width of the initial containing block, the height of the initial containing block is unspecified. &lt;/li&gt;     &lt;/ul&gt;   &lt;/li&gt; &lt;/ul&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7462882-8068654535726319242?l=gisresearch.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gisresearch.blogspot.com/feeds/8068654535726319242/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7462882&amp;postID=8068654535726319242' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7462882/posts/default/8068654535726319242'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7462882/posts/default/8068654535726319242'/><link rel='alternate' type='text/html' href='http://gisresearch.blogspot.com/2009/06/css-positioning.html' title='CSS positioning'/><author><name>J.W.</name><uri>http://www.blogger.com/profile/09241601264454722977</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://farm3.static.flickr.com/2116/1856041089_20ef060d43_o.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7462882.post-602556629041968372</id><published>2009-06-19T10:04:00.001-04:00</published><updated>2009-06-19T10:04:10.793-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='CSS'/><title type='text'>CSS margin and Padding</title><content type='html'>&lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh5.ggpht.com/_skGtCbVaJ2o/Sjua2XQYejI/AAAAAAAABRg/KqK264LgjkI/s1600-h/image%5B8%5D.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://lh6.ggpht.com/_skGtCbVaJ2o/Sjua2oFoH0I/AAAAAAAABRk/GVJuxJMpxmU/image_thumb%5B6%5D.png?imgmax=800" width="644" height="471" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;The difference between “margin” and “padding” is that Margin is outside of the box,while the padding is inside the box.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7462882-602556629041968372?l=gisresearch.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gisresearch.blogspot.com/feeds/602556629041968372/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7462882&amp;postID=602556629041968372' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7462882/posts/default/602556629041968372'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7462882/posts/default/602556629041968372'/><link rel='alternate' type='text/html' href='http://gisresearch.blogspot.com/2009/06/css-margin-and-padding.html' title='CSS margin and Padding'/><author><name>J.W.</name><uri>http://www.blogger.com/profile/09241601264454722977</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://farm3.static.flickr.com/2116/1856041089_20ef060d43_o.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh6.ggpht.com/_skGtCbVaJ2o/Sjua2oFoH0I/AAAAAAAABRk/GVJuxJMpxmU/s72-c/image_thumb%5B6%5D.png?imgmax=800' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7462882.post-2690159924009008897</id><published>2009-06-12T16:49:00.001-04:00</published><updated>2009-06-21T19:47:05.400-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Asp.Net'/><title type='text'>Learn NInject, FluentNHibernate, NHibernate through Canvas example – 1 ( Set up the NInjector in application start)</title><content type='html'>&lt;p&gt;&lt;a href="http://code.google.com/p/codebettercanvas/"&gt;Codebettercanvas&lt;/a&gt; is a learning application published by Karl Seguin to teach some best practices around very cool oss projects such as &lt;a href="http://ninject.org/"&gt;NInject&lt;/a&gt;, &lt;a href="https://www.hibernate.org/343.html"&gt;NHibernate&lt;/a&gt;, &lt;a href="http://jquery.com/"&gt;JQuery&lt;/a&gt;, &lt;a href="http://logging.apache.org/log4net/index.html"&gt;log4Net&lt;/a&gt;. This is a more advanced example than the previous examples such as &lt;a href="http://www.asp.net/mvc/learn/"&gt;NerdDinner&lt;/a&gt;, and &lt;a href="http://www.asp.net/mvc/learn/"&gt;Contact Manager&lt;/a&gt;.&amp;#160; I would definitely suggest going through those examples before reading the source code of this example.&lt;/p&gt;  &lt;p&gt;The codebettercanvas didn’t follow the default Asp.Net mvc project structure. The default project structure will have three separate folders called Controllers, Models, and Views. In this example, Karl put controllers, helpers, components and binders in different folder. The model itself is in a separate project.&lt;/p&gt;  &lt;p&gt;&lt;/p&gt; &lt;a href="http://lh6.ggpht.com/_skGtCbVaJ2o/SjsBACgePdI/AAAAAAAABRU/fcJsgd9iuiA/s1600-h/DefaultArchitecture%5B5%5D.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; margin-left: 0px; border-left-width: 0px; margin-right: 0px" title="DefaultArchitecture" border="0" alt="DefaultArchitecture" src="http://lh3.ggpht.com/_skGtCbVaJ2o/SjsAJbKO8dI/AAAAAAAABRY/jOh54Da1tbc/DefaultArchitecture_thumb.png?imgmax=800" width="185" height="217" /&gt;&lt;/a&gt; &lt;a href="http://lh5.ggpht.com/_skGtCbVaJ2o/SjsAJqe_OAI/AAAAAAAABRM/0Xyn0MYf3hY/s1600-h/CropperCapture%5B1%5D%5B4%5D.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; margin-left: 0px; border-left-width: 0px; margin-right: 0px" title="CropperCapture[1]" border="0" alt="CropperCapture[1]" src="http://lh3.ggpht.com/_skGtCbVaJ2o/SjsAKCrX9dI/AAAAAAAABRQ/M62eSxS890U/CropperCapture%5B1%5D_thumb%5B2%5D.png?imgmax=800" width="154" height="244" /&gt;&lt;/a&gt;   &lt;p&gt;I am not sure whether it’s a good idea or not, but I guess the example tries to show us the principle of “separation of concerns'”. The whole idea of MVC is “convention over configuration”, this directory structure change looks like a break from the default convention, so I am not very sure whether this is a good idea or not.&lt;/p&gt;  &lt;p&gt;The Global.aspx.cs is the entry point for the asp.net application, just like the Main function in the console program. It will be run at the first time the applications starts. Here is the code.&lt;/p&gt;  &lt;pre class="brush: csharp;"&gt;    public class MvcApplication :  NinjectHttpApplication &lt;br /&gt;    {&lt;br /&gt;        public override void Init()&lt;br /&gt;        {&lt;br /&gt;            Error += OnError;&lt;br /&gt;            EndRequest += OnEndRequest;&lt;br /&gt;            base.Init();&lt;br /&gt;        }    &lt;br /&gt;&lt;br /&gt;        public static void RegisterRoutes(RouteCollection routes)&lt;br /&gt;        {&lt;br /&gt;            routes.IgnoreRoute(&amp;quot;{resource}.axd/{*pathInfo}&amp;quot;);&lt;br /&gt;            routes.MapRoute(&amp;quot;Default&amp;quot;,&amp;quot;{controller}/{action}/{id}&amp;quot;, new { controller = &amp;quot;Home&amp;quot;, action = &amp;quot;Index&amp;quot;, id = &amp;quot;&amp;quot; });&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        protected override void OnApplicationStarted()&lt;br /&gt;        {&lt;br /&gt;            RegisterAllControllersIn(&amp;quot;CodeBetter.Canvas.Web&amp;quot;);&lt;br /&gt;         &lt;br /&gt;            log4net.Config.XmlConfigurator.Configure();&lt;br /&gt;            RegisterRoutes(RouteTable.Routes);&lt;br /&gt;&lt;br /&gt;            Factory.Load(new Components.WebDependencies());&lt;br /&gt;            ModelBinders.Binders.DefaultBinder = new Binders.GenericBinderResolver(Factory.TryGet&amp;lt;IModelBinder&amp;gt;);&lt;br /&gt;&lt;br /&gt;            ValidatorConfiguration.Initialize(&amp;quot;CodeBetter.Canvas&amp;quot;);&lt;br /&gt;            HtmlValidationExtensions.Initialize(ValidatorConfiguration.Rules);&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        private void OnEndRequest(object sender, System.EventArgs e)&lt;br /&gt;        {&lt;br /&gt;            if (((HttpApplication)sender).Context.Handler is MvcHandler)&lt;br /&gt;            {&lt;br /&gt;                CreateKernel().Get&amp;lt;ISessionSource&amp;gt;().Close();&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;        private void OnError(object sender, System.EventArgs e)&lt;br /&gt;        {&lt;br /&gt;            CreateKernel().Get&amp;lt;ISessionSource&amp;gt;().Close();&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        protected override IKernel CreateKernel()&lt;br /&gt;        {&lt;br /&gt;            return Factory.Kernel;&lt;br /&gt;        }&lt;br /&gt;    }    &lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;Instead of inheriting from the HttpApplication,&amp;#160; it chooses to inherit from NinjectHttpApplication. NinjectHttpApplication is an extender of HttpApplication which is based on NInject. Here is the code from the reflector.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: csharp;"&gt;public abstract class NinjectHttpApplication : HttpApplication, IHaveKernel&lt;br /&gt;{&lt;br /&gt;    // Fields&lt;br /&gt;    private static IKernel _kernel;&lt;br /&gt;&lt;br /&gt;    // Methods&lt;br /&gt;    protected NinjectHttpApplication();&lt;br /&gt;    public void Application_Start();&lt;br /&gt;    public void Application_Stop();&lt;br /&gt;    protected abstract IKernel CreateKernel();&lt;br /&gt;    private static string GetControllerName(Type type);&lt;br /&gt;    private static bool IsController(Type type);&lt;br /&gt;    protected virtual void OnApplicationStarted();&lt;br /&gt;    protected virtual void OnApplicationStopped();&lt;br /&gt;    public void RegisterAllControllersIn(Assembly assembly);&lt;br /&gt;    public void RegisterAllControllersIn(string assemblyName);&lt;br /&gt;    public void RegisterAllControllersIn(Assembly assembly, Func&amp;lt;Type, string&amp;gt; namingConvention);&lt;br /&gt;    public void RegisterAllControllersIn(string assemblyName, Func&amp;lt;Type, string&amp;gt; namingConvention);&lt;br /&gt;&lt;br /&gt;    // Properties&lt;br /&gt;    public IKernel Kernel { get; }&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;The first call in the OnApplicationStarted() of the MvcApplication class is RegisterAllControllersIn(&amp;quot;CodeBetter.Canvas.Web&amp;quot;), and this function is used to register all the controlles inside the assembly of &amp;quot;CodeBetter.Canvas.Web&amp;quot;, so NInject knows where to look for it in the later use. &lt;br /&gt;&lt;br /&gt;&lt;p&gt;By peeking inside NInject,Web.Mvc, The RegisterAllControllersIn will then call function RegisterAllControllersIn(assembly, &lt;strong&gt;new Func&amp;lt;Type, string&amp;gt;(NinjectHttpApplication.GetControllerName)&lt;/strong&gt;). NinjectHttpApplication.GetControllerName will take a control type name and return its name in string format. The function will expand like this:&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: csharp;"&gt;public void RegisterAllControllersIn(Assembly assembly, Func&amp;lt;Type, string&amp;gt; namingConvention)&lt;br /&gt;{&lt;br /&gt;    foreach (Type type in assembly.GetExportedTypes().Where&amp;lt;Type&amp;gt;(new Func&amp;lt;Type, bool&amp;gt;(NinjectHttpApplication.IsController)))&lt;br /&gt;    {&lt;br /&gt;        _kernel.Bind&amp;lt;IController&amp;gt;().To(type).InTransientScope().Named(namingConvention(type));&lt;br /&gt;    }&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;Basically, it will loop through all the controller types in the assembly, and bind the control type to the control name, which is calculated based on the function &lt;strong&gt;namingConvention(type).&amp;#160; &lt;/strong&gt;This will explain some magic binding in the later section.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;The next line is the configuration for log4Net, log4net.Config.XmlConfigurator.Configure(); This configuration is based on the configuration section in web.config &lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: xml;"&gt;  &amp;lt;log4net&amp;gt;&lt;br /&gt;        &amp;lt;appender name=&amp;quot;CustomTracer&amp;quot; type=&amp;quot;log4net.Appender.TraceAppender, log4net&amp;quot;&amp;gt;&lt;br /&gt;            &amp;lt;layout type=&amp;quot;log4net.Layout.SimpleLayout&amp;quot;/&amp;gt;&lt;br /&gt;        &amp;lt;/appender&amp;gt;&lt;br /&gt;        &amp;lt;root&amp;gt;&lt;br /&gt;            &amp;lt;level value=&amp;quot;DEBUG&amp;quot;/&amp;gt;&lt;br /&gt;            &amp;lt;appender-ref ref=&amp;quot;CustomTracer&amp;quot;/&amp;gt;&lt;br /&gt;        &amp;lt;/root&amp;gt;&lt;br /&gt;        &amp;lt;logger name=&amp;quot;NHibernate&amp;quot;&amp;gt;&lt;br /&gt;            &amp;lt;level value=&amp;quot;ALL&amp;quot;/&amp;gt;&lt;br /&gt;            &amp;lt;appender-ref ref=&amp;quot;CustomTracer&amp;quot;/&amp;gt;&lt;br /&gt;        &amp;lt;/logger&amp;gt;&lt;br /&gt;    &amp;lt;/log4net&amp;gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;I am not very familiar with the log4Net, so I won’t explain too much here. &lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;The next line is Factory.Load(new Components.WebDependencies()), which will load all the web dependencies. Factory is a static helper class to work with NInject.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: csharp;"&gt;   public static class Factory&lt;br /&gt;    {&lt;br /&gt;        private static readonly IKernel _kernel = new StandardKernel(new CoreDependencies());&lt;br /&gt;&lt;br /&gt;        public static IKernel Kernel&lt;br /&gt;        {&lt;br /&gt;            get { return _kernel; }&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        public static T Get&amp;lt;T&amp;gt;()&lt;br /&gt;        {&lt;br /&gt;            return _kernel.Get&amp;lt;T&amp;gt;();&lt;br /&gt;        }&lt;br /&gt;        public static T Get&amp;lt;T&amp;gt;(Type type)&lt;br /&gt;        {&lt;br /&gt;            return (T) _kernel.Get(type);&lt;br /&gt;        }&lt;br /&gt;        public static T TryGet&amp;lt;T&amp;gt;()&lt;br /&gt;        {&lt;br /&gt;            return _kernel.TryGet&amp;lt;T&amp;gt;();&lt;br /&gt;        }&lt;br /&gt;        public static T TryGet&amp;lt;T&amp;gt;(Type type)&lt;br /&gt;        {&lt;br /&gt;            return (T)_kernel.TryGet(type);&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        public static void Load(INinjectModule module)&lt;br /&gt;        {            &lt;br /&gt;            _kernel.Load(module);&lt;br /&gt;        }&lt;br /&gt;    }&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;and the WebDependencies is inherited from NinjectModule &lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: csharp;"&gt;    public class WebDependencies : NinjectModule&lt;br /&gt;    {&lt;br /&gt;        public override void Load()&lt;br /&gt;        {&lt;br /&gt;            Bind&amp;lt;IAuthenticationManager&amp;gt;().To&amp;lt;AuthenticationManager&amp;gt;().InRequestScope();&lt;br /&gt;            Bind&amp;lt;ModelBinder&amp;lt;User&amp;gt;&amp;gt;().To&amp;lt;UserBinder&amp;gt;().InRequestScope();&lt;br /&gt;        }&lt;br /&gt;    }&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;By binding the WebDependencies , next time, if the application requests IAuthenticationManager, the AuthenticationManager will return to meet the request. If the application requests ModelBinder&amp;lt;User&amp;gt;,&amp;#160; then UserBinder will return. Besides the WebDependencies , the Factory also initializes a static kernel which retains a reference to the CoreDependencies: &lt;em&gt;&lt;font color="#ff0000"&gt;private static readonly IKernel _kernel = new StandardKernel(new CoreDependencies());&lt;/font&gt;&lt;/em&gt; &lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: csharp;"&gt;  public class CoreDependencies : NinjectModule&lt;br /&gt;    {&lt;br /&gt;        public override void Load()&lt;br /&gt;        {&lt;br /&gt;            var connectionString = string.Format(&amp;quot;Data Source={0};Version=3;New=False;&amp;quot;, Configuration.GetConfig().ConnectionString);&lt;br /&gt;            var configuration = Fluently.Configure()&lt;br /&gt;                .Database(SQLiteConfiguration.Standard.ConnectionString(c =&amp;gt; c.Is(connectionString)))&lt;br /&gt;                .Mappings(m =&amp;gt; m.FluentMappings&lt;br /&gt;                                .AddFromAssemblyOf&amp;lt;User&amp;gt;()&lt;br /&gt;                                .ConventionDiscovery.AddFromAssemblyOf&amp;lt;TableNameConvention&amp;gt;());&lt;br /&gt;&lt;br /&gt;            Bind&amp;lt;ISessionSource&amp;gt;()&lt;br /&gt;                .To&amp;lt;SessionSource&amp;gt;()&lt;br /&gt;                .InRequestScope()&lt;br /&gt;                .WithConstructorArgument(&amp;quot;config&amp;quot;, configuration);&lt;br /&gt;&lt;br /&gt;            Bind&amp;lt;IUserRepository&amp;gt;().To&amp;lt;UserRepository&amp;gt;().InRequestScope();&lt;br /&gt;            Bind&amp;lt;IValidator&amp;gt;().To&amp;lt;Validator&amp;gt;();&lt;br /&gt;            Bind&amp;lt;IEncryptor&amp;gt;().To&amp;lt;Encryptor&amp;gt;();&lt;br /&gt;        }&lt;br /&gt;    }&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;Next line is to &lt;strong&gt;replace&lt;/strong&gt; the default model binder with a customized model binder as this:&amp;#160; ModelBinders.Binders.DefaultBinder = new Binders.GenericBinderResolver(Factory.TryGet&amp;lt;IModelBinder&amp;gt;); This further demonstrates that Asp.net MVC is highly extensible architecture.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;The next two lines are validation configuration &lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: csharp;"&gt;          ValidatorConfiguration.Initialize(&amp;quot;CodeBetter.Canvas&amp;quot;);&lt;br /&gt;            HtmlValidationExtensions.Initialize(ValidatorConfiguration.Rules);&lt;/pre&gt;&lt;br /&gt;The validation logic deserves another seperate post. &lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;That’s about everything when the application starts, and in my view, it’s the most important step to set everything up.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7462882-2690159924009008897?l=gisresearch.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gisresearch.blogspot.com/feeds/2690159924009008897/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7462882&amp;postID=2690159924009008897' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7462882/posts/default/2690159924009008897'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7462882/posts/default/2690159924009008897'/><link rel='alternate' type='text/html' href='http://gisresearch.blogspot.com/2009/06/learn-ninject-fluentnhibernate.html' title='Learn NInject, FluentNHibernate, NHibernate through Canvas example – 1 ( Set up the NInjector in application start)'/><author><name>J.W.</name><uri>http://www.blogger.com/profile/09241601264454722977</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://farm3.static.flickr.com/2116/1856041089_20ef060d43_o.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh3.ggpht.com/_skGtCbVaJ2o/SjsAJbKO8dI/AAAAAAAABRY/jOh54Da1tbc/s72-c/DefaultArchitecture_thumb.png?imgmax=800' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7462882.post-959260416933610141</id><published>2009-06-10T16:53:00.001-04:00</published><updated>2009-06-10T16:55:07.451-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Asp.Net MVC'/><title type='text'>Learn Asp.Net mvc through NerdDinner Example</title><content type='html'>&lt;p&gt;&lt;a href="http://www.asp.net/mvc/learn/"&gt;NerdDinner&lt;/a&gt; is another example which is developed by Microsoft to demonstrate the way to build asp.net mvc application. The contact manger example is developed by Stephen Walther, while the NerdDinner is developed by &lt;a href="http://www.hanselman.com"&gt;Scott Hanselman&lt;/a&gt;. Both are very gurus in the asp.net mvc fields.&lt;/p&gt;  &lt;p&gt;Similar to the contact management example, it uses a repository pattern to CRUD data, &lt;/p&gt;  &lt;pre class="brush: csharp;"&gt;    public interface IDinnerRepository {&lt;br /&gt;&lt;br /&gt;        IQueryable&lt;dinner&gt; FindAllDinners();&lt;br /&gt;        IQueryable&lt;dinner&gt; FindByLocation(float latitude, float longitude);&lt;br /&gt;        IQueryable&lt;dinner&gt; FindUpcomingDinners();&lt;br /&gt;        Dinner GetDinner(int id);&lt;br /&gt;&lt;br /&gt;        void Add(Dinner dinner);&lt;br /&gt;        void Delete(Dinner dinner);&lt;br /&gt;        &lt;br /&gt;        void Save();&lt;br /&gt;    }&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;The difference is &lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;ol&gt;&lt;br /&gt;  &lt;li&gt;NerdDinner uses LINQ2SQL while the ContactManagment uses the entity framework. &lt;/li&gt;&lt;br /&gt;  &lt;li&gt;ContactManagment&amp;#160; uses a service layer to bridge the communication between control and the model, while the NerdDinner passes the repository layer to the controller directly. Personally, I like the service layer a little better even it causes another layer of indirection. &lt;/li&gt;&lt;br /&gt;  &lt;li&gt;ContactManagment&amp;#160;&amp;#160; uses IValidationDictionary and a ModelStateWrapper wrapper to manage the validation logic. This ModelStateWrapper will be passed to the service layer in turn.&lt;br /&gt;    &lt;pre class="brush: csharp;"&gt;    public interface IValidationDictionary&lt;br /&gt;    {&lt;br /&gt;        void AddError(string key, string errorMessage);&lt;br /&gt;        bool IsValid {get;}&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public class ModelStateWrapper : IValidationDictionary&lt;br /&gt;    {&lt;br /&gt;        private ModelStateDictionary _modelState;&lt;br /&gt;&lt;br /&gt;        public ModelStateWrapper(ModelStateDictionary modelState)&lt;br /&gt;        {&lt;br /&gt;            _modelState = modelState;&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        public void AddError(string key, string errorMessage)&lt;br /&gt;        {&lt;br /&gt;            _modelState.AddModelError(key, errorMessage);&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        public bool IsValid&lt;br /&gt;        {&lt;br /&gt;            get { return _modelState.IsValid; }&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;while NerdDinner uses RuleViolation object to manage the error.&lt;/li&gt;&lt;br /&gt;&lt;br /&gt;  &lt;pre class="brush: csharp;"&gt;public class RuleViolation {&lt;br /&gt;&lt;br /&gt;        public string ErrorMessage { get; private set; }&lt;br /&gt;        public string PropertyName { get; private set; }&lt;br /&gt;&lt;br /&gt;        public RuleViolation(string errorMessage) {&lt;br /&gt;            ErrorMessage = errorMessage;&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        public RuleViolation(string errorMessage, string propertyName) {&lt;br /&gt;            ErrorMessage = errorMessage;&lt;br /&gt;            PropertyName = propertyName;&lt;br /&gt;        }&lt;br /&gt;    }&lt;/pre&gt; and defines  public IEnumerable&lt;RuleViolation&gt; GetRuleViolations() on the business class Dinner directly. &lt;br /&gt;&lt;br /&gt;  &lt;pre class="brush: csharp;"&gt;&lt;br /&gt;public partial class Dinner {&lt;br /&gt; public bool IsValid {&lt;br /&gt;            get { return (GetRuleViolations().Count() == 0); }&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        public IEnumerable&lt;RuleViolation&gt; GetRuleViolations() {&lt;br /&gt;&lt;br /&gt;            if (String.IsNullOrEmpty(Title))&lt;br /&gt;                yield return new RuleViolation("Title is required", "Title");&lt;br /&gt;&lt;br /&gt;            if (String.IsNullOrEmpty(Description))&lt;br /&gt;                yield return new RuleViolation("Description is required", "Description");&lt;br /&gt;&lt;br /&gt;            if (String.IsNullOrEmpty(HostedBy))&lt;br /&gt;                yield return new RuleViolation("HostedBy is required", "HostedBy");&lt;br /&gt;&lt;br /&gt;            if (String.IsNullOrEmpty(Address))&lt;br /&gt;                yield return new RuleViolation("Address is required", "Address");&lt;br /&gt;&lt;br /&gt;            if (String.IsNullOrEmpty(Country))&lt;br /&gt;                yield return new RuleViolation("Country is required", "Address");&lt;br /&gt;&lt;br /&gt;            if (String.IsNullOrEmpty(ContactPhone))&lt;br /&gt;                yield return new RuleViolation("Phone# is required", "ContactPhone");&lt;br /&gt;&lt;br /&gt;            if (!PhoneValidator.IsValidNumber(ContactPhone, Country))&lt;br /&gt;                yield return new RuleViolation("Phone# does not match country", "ContactPhone");&lt;br /&gt;&lt;br /&gt;            yield break;&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        partial void OnValidate(ChangeAction action) {//partial method for LINQ generated code.&lt;br /&gt;            if (!IsValid)&lt;br /&gt;                throw new ApplicationException("Rule violations prevent saving");&lt;br /&gt;        }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;I cannot say which is better, but I still prefer the Contact Manager Example.&lt;br /&gt;&lt;/ol&gt;&lt;br /&gt;Both projects use Moq framework to mock the interface and abstract class.&lt;br /&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7462882-959260416933610141?l=gisresearch.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gisresearch.blogspot.com/feeds/959260416933610141/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7462882&amp;postID=959260416933610141' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7462882/posts/default/959260416933610141'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7462882/posts/default/959260416933610141'/><link rel='alternate' type='text/html' href='http://gisresearch.blogspot.com/2009/06/learn-aspnet-mvc-through-nerddinner.html' title='Learn Asp.Net mvc through NerdDinner Example'/><author><name>J.W.</name><uri>http://www.blogger.com/profile/09241601264454722977</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://farm3.static.flickr.com/2116/1856041089_20ef060d43_o.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7462882.post-4697169065725282192</id><published>2009-06-10T10:34:00.001-04:00</published><updated>2009-06-10T10:34:05.990-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='OSS'/><title type='text'>Sourceforge top downloads</title><content type='html'>&lt;p&gt;This is a really &lt;a href="http://sourceforge.net/top/topalltime.php?type=downloads"&gt;interesting list – Soruceforge top downloads&lt;/a&gt;.&amp;#160; &lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh6.ggpht.com/_skGtCbVaJ2o/Si_EXJYiWDI/AAAAAAAABQ8/vP71YYtGh6w/s1600-h/image%5B2%5D.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://lh4.ggpht.com/_skGtCbVaJ2o/Si_EXf4LeiI/AAAAAAAABRA/l5vQSPAHCuo/image_thumb.png?imgmax=800" width="244" height="105" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;All top 3 are file sharing programs. Should we feel sad about that. And if you dig further, other file sharing programs are on the top too. &lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7462882-4697169065725282192?l=gisresearch.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gisresearch.blogspot.com/feeds/4697169065725282192/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7462882&amp;postID=4697169065725282192' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7462882/posts/default/4697169065725282192'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7462882/posts/default/4697169065725282192'/><link rel='alternate' type='text/html' href='http://gisresearch.blogspot.com/2009/06/sourceforge-top-downloads.html' title='Sourceforge top downloads'/><author><name>J.W.</name><uri>http://www.blogger.com/profile/09241601264454722977</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://farm3.static.flickr.com/2116/1856041089_20ef060d43_o.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh4.ggpht.com/_skGtCbVaJ2o/Si_EXf4LeiI/AAAAAAAABRA/l5vQSPAHCuo/s72-c/image_thumb.png?imgmax=800' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7462882.post-7229200955166348370</id><published>2009-06-09T20:42:00.001-04:00</published><updated>2009-06-10T14:36:24.082-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Asp.Net MVC'/><title type='text'>Learn Asp.Net mvc through ContactManager Example ( The architecture)</title><content type='html'>&lt;p&gt;I downloaded the asp.net mvc ContactManager Example &lt;a href="http://www.asp.net/mvc/learn/"&gt;from asp.net website&lt;/a&gt;. This is a very good example written by &lt;a href="http://stephenwalther.com/blog/default.aspx"&gt;Stephen Walther&lt;/a&gt;. &lt;/p&gt;  &lt;p&gt;This example uses the Entity framework as the data access layer, the whole model is very simple and only contains two tables. A couple of points worth mentioning is :&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;In the control constructor, never pass in the concrete class , instead , pass in interface ONLY.&amp;#160; This will enable easy testing, and work nicely with Mock frame work. &lt;/li&gt;    &lt;li&gt;Define a Repository wrapper to wrap the entity data model. Notice this will be the interface to pass to the other business class. The Repository wrapper should do simply read/write operation.      &lt;pre class="brush: csharp;"&gt; public interface IContactManagerRepository&lt;br /&gt;    {&lt;br /&gt;        // Contact methods&lt;br /&gt;        Contact CreateContact(int groupId, Contact contactToCreate);&lt;br /&gt;        void DeleteContact(Contact contactToDelete);&lt;br /&gt;        Contact EditContact(int groupId, Contact contactToEdit);&lt;br /&gt;        Contact GetContact(int id);&lt;br /&gt;&lt;br /&gt;        // Group methods&lt;br /&gt;        Group CreateGroup(Group groupToCreate);&lt;br /&gt;        IEnumerable&amp;lt;Group&amp;gt; ListGroups();&lt;br /&gt;        Group GetGroup(int groupId);&lt;br /&gt;        Group GetFirstGroup();&lt;br /&gt;        void DeleteGroup(Group groupToDelete);&lt;br /&gt;    }&lt;/pre&gt;&lt;/li&gt;&lt;br /&gt;&lt;br /&gt;  &lt;li&gt;Define another interface called IContactManagerService which has very similar methods like the IContactManagerRepository except this interface does some additional business validation beside the CRUD operation.     &lt;br /&gt;    &lt;pre class="brush: csharp;"&gt; public interface IContactManagerService&lt;br /&gt;    {&lt;br /&gt;        bool CreateContact(int groupId, Contact contactToCreate);&lt;br /&gt;        bool DeleteContact(Contact contactToDelete);&lt;br /&gt;        bool EditContact(int groupId, Contact contactToEdit);&lt;br /&gt;        Contact GetContact(int id);&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;        bool CreateGroup(Group groupToCreate);&lt;br /&gt;        IEnumerable&lt;group&gt; ListGroups();&lt;br /&gt;        Group GetGroup(int? id);&lt;br /&gt;        bool DeleteGroup(Group groupToDelete);&lt;br /&gt;    }&lt;/pre&gt;&lt;br /&gt;&lt;/li&gt;&lt;br /&gt;  &lt;li&gt;Create an EntityContactManagerRepository class to implement the IContactManagerRepository service. The entity framework generated data access class will be an internal member, and all the CRUD operation will be delegated to the entity object. &lt;br /&gt;&lt;/li&gt;&lt;br /&gt;&lt;br /&gt;  &lt;li&gt;Define a class called ContactManagerService to implement IContactManagerService,ContactManagerService will also take a IValidationDictionary as its member. Here are its two constructors. &lt;br /&gt;    &lt;pre class="brush: csharp;"&gt; &lt;br /&gt;        public ContactManagerService(IValidationDictionary validationDictionary) &lt;br /&gt;            : this(validationDictionary, new EntityContactManagerRepository())&lt;br /&gt;        {}&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;        public ContactManagerService(IValidationDictionary validationDictionary, IContactManagerRepository repository)&lt;br /&gt;        {&lt;br /&gt;            _validationDictionary = validationDictionary;&lt;br /&gt;            _repository = repository;&lt;br /&gt;        }&lt;/pre&gt;&lt;br /&gt;&lt;/li&gt;&lt;br /&gt;&lt;br /&gt;  &lt;li&gt;Define a class called ModelStateWrapper to implement IValidationDictionary &lt;br /&gt;    &lt;pre class="brush: csharp;"&gt; &lt;br /&gt; public class ModelStateWrapper : IValidationDictionary&lt;br /&gt;    {&lt;br /&gt;        private ModelStateDictionary _modelState;&lt;br /&gt;&lt;br /&gt;        public ModelStateWrapper(ModelStateDictionary modelState)&lt;br /&gt;        {&lt;br /&gt;            _modelState = modelState;&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        public void AddError(string key, string errorMessage)&lt;br /&gt;        {&lt;br /&gt;            _modelState.AddModelError(key, errorMessage);&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        public bool IsValid&lt;br /&gt;        {&lt;br /&gt;            get { return _modelState.IsValid; }&lt;br /&gt;        }&lt;br /&gt;    }&lt;/pre&gt;&lt;br /&gt;&lt;/li&gt;&lt;br /&gt;  &lt;li&gt;In the controller code, it takes the business interface IContactManagerService as a parameter. Notice ContactManagerService takes &lt;strong&gt;IValidationDictionary for validation&lt;/strong&gt; and &lt;strong&gt;IContactManagerRepository for data access&lt;/strong&gt;. &lt;br /&gt;    &lt;pre class="brush: csharp;"&gt; &lt;br /&gt;    public class GroupController : Controller&lt;br /&gt;    {&lt;br /&gt;&lt;br /&gt;        private IContactManagerService _service;&lt;br /&gt;&lt;br /&gt;        public GroupController()&lt;br /&gt;        {&lt;br /&gt;            _service = new ContactManagerService(new ModelStateWrapper(this.ModelState));&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        public GroupController(IContactManagerService service)&lt;br /&gt;        {&lt;br /&gt;            _service = service;&lt;br /&gt;        }&lt;br /&gt;      ****&lt;br /&gt;    }&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;The interesting point is that the example doesn't pass the IContactManagerRepository into the controller, it is hidden behind the IContactManagerService interface, which is passed into the controller interface. &lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7462882-7229200955166348370?l=gisresearch.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gisresearch.blogspot.com/feeds/7229200955166348370/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7462882&amp;postID=7229200955166348370' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7462882/posts/default/7229200955166348370'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7462882/posts/default/7229200955166348370'/><link rel='alternate' type='text/html' href='http://gisresearch.blogspot.com/2009/06/learn-aspnet-mvc-through-contactmanager.html' title='Learn Asp.Net mvc through ContactManager Example ( The architecture)'/><author><name>J.W.</name><uri>http://www.blogger.com/profile/09241601264454722977</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://farm3.static.flickr.com/2116/1856041089_20ef060d43_o.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7462882.post-7217885894343615279</id><published>2009-06-05T11:07:00.001-04:00</published><updated>2009-06-05T11:07:24.581-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Tools'/><category scheme='http://www.blogger.com/atom/ns#' term='Visual Studio'/><title type='text'>Use Shelving and Unshelving in TFS.</title><content type='html'>&lt;p&gt;I have been reading some documentation about shelving and unshelving in TFS, but still don’t have a clear idea on what exactly means until I watch &lt;a href="http://msdn.microsoft.com/en-us/teamsystem/bb905524.aspx"&gt;this video&lt;/a&gt;. I would highly recommend people to watch this video if they have question about those features. &lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7462882-7217885894343615279?l=gisresearch.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gisresearch.blogspot.com/feeds/7217885894343615279/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7462882&amp;postID=7217885894343615279' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7462882/posts/default/7217885894343615279'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7462882/posts/default/7217885894343615279'/><link rel='alternate' type='text/html' href='http://gisresearch.blogspot.com/2009/06/use-shelving-and-unshelving-in-tfs.html' title='Use Shelving and Unshelving in TFS.'/><author><name>J.W.</name><uri>http://www.blogger.com/profile/09241601264454722977</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://farm3.static.flickr.com/2116/1856041089_20ef060d43_o.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7462882.post-546817398343754695</id><published>2009-05-21T11:40:00.001-04:00</published><updated>2009-05-21T11:40:02.681-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Programming'/><category scheme='http://www.blogger.com/atom/ns#' term='algorithm'/><category scheme='http://www.blogger.com/atom/ns#' term='Book'/><title type='text'>Steps to think about an algorithm problem</title><content type='html'>&lt;p&gt;I am reading the book &lt;a href="http://www.amazon.com/Think-About-Algorithms-Jeff-Edmonds/dp/0521614104"&gt;How to Think About Algorithms&lt;/a&gt;, and find this book very interesting to read. Compare to traditional algorithm books which mainly explain how&amp;#160; the algorithm work, this book takes a more “head first” approach, try to explain how you should think about algorithm. The style is close to &lt;a href="http://www.amazon.com/First-Design-Patterns-Elisabeth-Freeman/dp/0596007124/ref=sr_1_1?ie=UTF8&amp;amp;s=books&amp;amp;qid=1242920330&amp;amp;sr=1-1"&gt;Head First Design Pattern&lt;/a&gt;, which of course focus more on design pattern.&lt;/p&gt;  &lt;p&gt;The basic steps are:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;Specifications&lt;/li&gt;    &lt;li&gt;Basic Steps&lt;/li&gt;    &lt;li&gt;Measure of Progress&lt;/li&gt;    &lt;li&gt;The Loop Invariant&lt;/li&gt;    &lt;li&gt;Main Steps&lt;/li&gt;    &lt;li&gt;Make Progress&lt;/li&gt;    &lt;li&gt;Maintain Loop Invariant&lt;/li&gt;    &lt;li&gt;Establishing the Loop Invariant&lt;/li&gt;    &lt;li&gt;Exit Condition&lt;/li&gt;    &lt;li&gt;Ending&lt;/li&gt;    &lt;li&gt;Termination and Running Time&lt;/li&gt;    &lt;li&gt;Special Cases&lt;/li&gt;    &lt;li&gt;Coding and Implementation Details&lt;/li&gt; &lt;/ol&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7462882-546817398343754695?l=gisresearch.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gisresearch.blogspot.com/feeds/546817398343754695/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7462882&amp;postID=546817398343754695' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7462882/posts/default/546817398343754695'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7462882/posts/default/546817398343754695'/><link rel='alternate' type='text/html' href='http://gisresearch.blogspot.com/2009/05/steps-to-think-about-algorithm-problem.html' title='Steps to think about an algorithm problem'/><author><name>J.W.</name><uri>http://www.blogger.com/profile/09241601264454722977</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://farm3.static.flickr.com/2116/1856041089_20ef060d43_o.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7462882.post-1732708048941038143</id><published>2009-05-19T16:14:00.001-04:00</published><updated>2009-06-09T20:23:16.107-04:00</updated><title type='text'>Associate enter button with submit action using JQuery in Asp.Net</title><content type='html'>&lt;p&gt;I am working on a problem to associate a “enter” button with submit action with JQuery. It is probably a relatively easy work for JQuery expert, but it did took me some time to find a good solution.&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;Include the required javascript file. The way I used to include javascript files is to register them in Page_Init of code-behind.      &lt;pre class="brush: csharp;"&gt;    protected void Page_Init(object sender, EventArgs e)&lt;br /&gt;    {&lt;br /&gt;&lt;br /&gt;        HtmlGenericControl jQueryScript = new HtmlGenericControl(&amp;quot;script&amp;quot;);&lt;br /&gt;        jQueryScript.Attributes.Add(&amp;quot;type&amp;quot;, &amp;quot;text/javascript&amp;quot;);&lt;br /&gt;        jQueryScript.Attributes.Add(&amp;quot;src&amp;quot;, ResolveClientUrl(&amp;quot;~/Includes/jquery-1.2.6.min.js&amp;quot;));&lt;br /&gt;        this.Page.Header.Controls.Add(jQueryScript);&lt;br /&gt;    }&lt;/pre&gt;&lt;br /&gt;  &lt;/li&gt;&lt;br /&gt;&lt;br /&gt;  &lt;li&gt;Register the keydown event with the document, and trigger the submit action when the keydown code is 13. I identify the default submit button with a special css attribute “defaultbutton”, since the asp.net web form framework create complicated Ids and names, it’s much easier to use the css class instead. &lt;br /&gt;    &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;    &lt;pre class="brush: js;"&gt;      $(document).keydown(function(event) {&lt;br /&gt;          if (event.keyCode == 13) {&lt;br /&gt;              //not working: __doPostBack('__Page', 'EnteryKey');&lt;br /&gt;              //find default button.&lt;br /&gt;              var submitButton = $(&amp;quot;.defaultbutton&amp;quot;).get(0);&lt;br /&gt;              if (submitButton != null) {&lt;br /&gt;                  submitButton.click();&lt;br /&gt;              }&lt;br /&gt;          }&lt;br /&gt;      });       &lt;br /&gt;That’s it. &lt;/pre&gt;&lt;br /&gt;  &lt;/li&gt;&lt;br /&gt;&lt;/ol&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7462882-1732708048941038143?l=gisresearch.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gisresearch.blogspot.com/feeds/1732708048941038143/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7462882&amp;postID=1732708048941038143' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7462882/posts/default/1732708048941038143'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7462882/posts/default/1732708048941038143'/><link rel='alternate' type='text/html' href='http://gisresearch.blogspot.com/2009/05/associate-enter-button-with-submit.html' title='Associate enter button with submit action using JQuery in Asp.Net'/><author><name>J.W.</name><uri>http://www.blogger.com/profile/09241601264454722977</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://farm3.static.flickr.com/2116/1856041089_20ef060d43_o.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7462882.post-746734092393416560</id><published>2009-05-17T11:17:00.001-04:00</published><updated>2009-05-17T11:26:15.378-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Life'/><title type='text'>I read this from a comment on blog title “At This Point, I’d Prefer Java Developers Over .NET Developers”.</title><content type='html'>&lt;p&gt;This is a very interesting comment.&lt;/p&gt;  &lt;p&gt;The post is from &lt;a href="http://davybrion.com/blog/2009/04/at-this-point-id-prefer-java-developers-over-net-developers/"&gt;here&lt;/a&gt;. &lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;The reality is this: software development is a very tough career. With the amount of time we have to invest keeping up with the latest technologies we could have achieved greater mastery in a less rapidly changing field. For example I’ve always had a passion for computers while a good friend had a passion for medicine. He’s now a radiologist making $400,000 a year working less than I do. While money can buy nice things, more importantly it buys things like a solid future for your family. There are other important things though. He has more time to spend with his family, and he has the satisfaction of becoming more and more expert at his specialty over time because its rate of change is manageable. Meanwhile for us developers, no matter how we improve at the craft of writing software we still have a constant learning curve keeping up with new technologies. We will never achieve a high level of mastery at anything because we can’t afford to gamble that any given area won’t become obsolete by the time we do. With that and with constantly working to get better at creating correct, clear, maintainable code under constant time and business constraints, what we don’t have time for is getting distracted by bloviating evangelists for every new architecture/process concept that comes down the pike. The developers I respect are the ones who have weathered enough of this nonsense to know that there never has been and there never will be One Correct Development Religion. People with too much time on their hands come up with this endless bullshit and then the fanboys pull out their dicks and try to measure them by who gets more excited about the latest end-all-be-all concept(s). If you want to go by subjective personal samples, fine: every developer I’ve ever met who got overly excited about the dozens of acronyms/word salads-of-the-day that more often than not lead to greater complexity in a project has been something of an arrogant, narrow-minded dick. Like other engineers our job is to produce concrete results to move the business forward, and we have to deal with many variables and imperfections such that there can never be a single recipe for all projects. It’s necessary to be professional, flexible, adaptable, and get things done to meet the business objectives. Management doesn’t care about your quest for the ultimate coding religion and neither do your coworkers. All the endless narrow-minded debating about the merits of this or that approach just kills the joy of coding IMO, and I wouldn’t want to work with such people.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7462882-746734092393416560?l=gisresearch.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gisresearch.blogspot.com/feeds/746734092393416560/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7462882&amp;postID=746734092393416560' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7462882/posts/default/746734092393416560'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7462882/posts/default/746734092393416560'/><link rel='alternate' type='text/html' href='http://gisresearch.blogspot.com/2009/05/i-read-this-from-comment-on-blog-title.html' title='I read this from a comment on blog title “At This Point, I’d Prefer Java Developers Over .NET Developers”.'/><author><name>J.W.</name><uri>http://www.blogger.com/profile/09241601264454722977</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://farm3.static.flickr.com/2116/1856041089_20ef060d43_o.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7462882.post-966979618264786525</id><published>2009-01-08T08:51:00.001-05:00</published><updated>2009-01-08T08:51:04.915-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Windows'/><title type='text'>Find out how your computer get crashed in windows vista.</title><content type='html'>&lt;p&gt;My vista computer gets crashed randomly, and every time, when the computer crashes, it saves a file into crash directory. In windows vista. This directory will be “C:\Windows\Minidump”.&amp;#160; What you can do is to start a windbg console, and open the file in directory.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh3.ggpht.com/_skGtCbVaJ2o/SWYEuzSt3OI/AAAAAAAAAwM/jiIczxPGZHY/s1600-h/image3.png"&gt;&lt;img title="image" style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="568" alt="image" src="http://lh6.ggpht.com/_skGtCbVaJ2o/SWYEvTz-38I/AAAAAAAAAwQ/4Lw8jn63Iqs/image_thumb1.png?imgmax=800" width="730" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;This will take you to this screen.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh4.ggpht.com/_skGtCbVaJ2o/SWYEwKBBIFI/AAAAAAAAAwU/ZEXbqYTjwoU/s1600-h/image7.png"&gt;&lt;img title="image" style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="584" alt="image" src="http://lh5.ggpht.com/_skGtCbVaJ2o/SWYEwnuIT0I/AAAAAAAAAwY/v5lxpePDK_o/image_thumb3.png?imgmax=800" width="793" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;Just click on the !analyze – v, this will give you further information.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh6.ggpht.com/_skGtCbVaJ2o/SWYExpLF5JI/AAAAAAAAAwc/B4EsjvzZJBU/s1600-h/image11.png"&gt;&lt;img title="image" style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="588" alt="image" src="http://lh3.ggpht.com/_skGtCbVaJ2o/SWYEyN0sMLI/AAAAAAAAAwg/GMlUzglpfms/image_thumb5.png?imgmax=800" width="797" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;From my computer, it’s SBAlg.sys, the safeboot drive which caused the crash.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7462882-966979618264786525?l=gisresearch.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gisresearch.blogspot.com/feeds/966979618264786525/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7462882&amp;postID=966979618264786525' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7462882/posts/default/966979618264786525'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7462882/posts/default/966979618264786525'/><link rel='alternate' type='text/html' href='http://gisresearch.blogspot.com/2009/01/find-out-how-your-computer-get-crashed.html' title='Find out how your computer get crashed in windows vista.'/><author><name>J.W.</name><uri>http://www.blogger.com/profile/09241601264454722977</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://farm3.static.flickr.com/2116/1856041089_20ef060d43_o.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh6.ggpht.com/_skGtCbVaJ2o/SWYEvTz-38I/AAAAAAAAAwQ/4Lw8jn63Iqs/s72-c/image_thumb1.png?imgmax=800' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7462882.post-934716069802776136</id><published>2009-01-07T20:23:00.001-05:00</published><updated>2009-01-07T20:23:02.323-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='C#'/><category scheme='http://www.blogger.com/atom/ns#' term='Book'/><category scheme='http://www.blogger.com/atom/ns#' term='.Net'/><title type='text'>C# in depth</title><content type='html'>&lt;p&gt;I haven’t read a book from cover to cover for long time lately, but I spent a couple of days to read &lt;a href="http://csharpindepth.com/"&gt;C# in Depth&lt;/a&gt;. The author-Jon Skeet-is a talented person I admire. There are plenty of reviews on amazon site, I can only explain some of my thoughts. &lt;/p&gt;  &lt;p&gt;Too many programming books on the market is about teach you how to do thing, not in the manner why you should do that way. Even some authors tried to explain why, they tend to explain the problems from the expert’s perspective, NOT from the person who wants to learn to master the language. The examples given by the Jon are easy to follow and help you understand what’s exactly under the hood.&lt;/p&gt;  &lt;p&gt;This book is about c# 2.0/c# 3.0. When explaining the new features in c# 2.0/c# 3.0&amp;#160; such as anonymous methods, LINQ, Jon always traces the history back to explain how it is done before, and why it’s changed with the new features. This way, as the reader, I can always know the reason behind a new feature. In the easy-to-follow examples, Jon will always demo how it will be done in the old fashion way, then you could appreciate how those new features greatly improve the readability of the code.&lt;/p&gt;  &lt;p&gt;Jon also maintains a &lt;a href="http://msmvps.com/blogs/jon_skeet/default.aspx"&gt;blog&lt;/a&gt; to reflect his insight about C# in general and has a lot of in-depth articles.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7462882-934716069802776136?l=gisresearch.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gisresearch.blogspot.com/feeds/934716069802776136/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7462882&amp;postID=934716069802776136' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7462882/posts/default/934716069802776136'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7462882/posts/default/934716069802776136'/><link rel='alternate' type='text/html' href='http://gisresearch.blogspot.com/2009/01/c-in-depth.html' title='C# in depth'/><author><name>J.W.</name><uri>http://www.blogger.com/profile/09241601264454722977</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://farm3.static.flickr.com/2116/1856041089_20ef060d43_o.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7462882.post-2425858695103802201</id><published>2008-12-02T15:08:00.001-05:00</published><updated>2008-12-02T15:08:20.231-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='SQL'/><title type='text'>Database auditing trigger.</title><content type='html'>&lt;p&gt;I run in an interesting problem lately. One of my application needs some auditing abilities, it needs to write the change to the change history table if a particular field is updated.&lt;/p&gt;  &lt;p&gt;I google around, and found some information on MSDN, There is a T-sql statement called &lt;a href="http://msdn.microsoft.com/en-us/library/ms187326(SQL.90).aspx"&gt;UPDATE&lt;/a&gt;, and allows you check whether it's a field is updated or not.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh4.ggpht.com/_skGtCbVaJ2o/STWVr46PEDI/AAAAAAAAAlQ/nQRKT4dRq5k/s1600-h/image%5B8%5D.png"&gt;&lt;img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="410" alt="image" src="http://lh3.ggpht.com/_skGtCbVaJ2o/STWVs9n-e8I/AAAAAAAAAlU/9xvZJMwOQCs/image_thumb%5B6%5D.png?imgmax=800" width="644" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;So, I think if write some T-sql statement &lt;/p&gt;  &lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;If&lt;/span&gt; &lt;span class="kwrd"&gt;Update&lt;/span&gt;( field) &lt;br /&gt;&lt;span class="kwrd"&gt;BEGIN&lt;/span&gt;&lt;br /&gt;   //&lt;span class="kwrd"&gt;write&lt;/span&gt; &lt;span class="kwrd"&gt;to&lt;/span&gt; the another audit &lt;span class="kwrd"&gt;table&lt;/span&gt;.&lt;br /&gt;&lt;span class="kwrd"&gt;END&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;style type="text/css"&gt;&lt;br /&gt;.csharpcode, .csharpcode pre&lt;br /&gt;{&lt;br /&gt;	font-size: small;&lt;br /&gt;	color: black;&lt;br /&gt;	font-family: consolas, "Courier New", courier, monospace;&lt;br /&gt;	background-color: #ffffff;&lt;br /&gt;	/*white-space: pre;*/&lt;br /&gt;}&lt;br /&gt;.csharpcode pre { margin: 0em; }&lt;br /&gt;.csharpcode .rem { color: #008000; }&lt;br /&gt;.csharpcode .kwrd { color: #0000ff; }&lt;br /&gt;.csharpcode .str { color: #006080; }&lt;br /&gt;.csharpcode .op { color: #0000c0; }&lt;br /&gt;.csharpcode .preproc { color: #cc6633; }&lt;br /&gt;.csharpcode .asp { background-color: #ffff00; }&lt;br /&gt;.csharpcode .html { color: #800000; }&lt;br /&gt;.csharpcode .attr { color: #ff0000; }&lt;br /&gt;.csharpcode .alt &lt;br /&gt;{&lt;br /&gt;	background-color: #f4f4f4;&lt;br /&gt;	width: 100%;&lt;br /&gt;	margin: 0em;&lt;br /&gt;}&lt;br /&gt;.csharpcode .lnum { color: #606060; }&lt;/style&gt;&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;However, I was confused that the audit table keeps get new entries even I didn't change any data. Yes, that's trick, be aware the difference between &amp;quot;update&amp;quot; and &amp;quot;change&amp;quot;, the If Update(filed) will returns true even you don't modify any data. If you want to log to the another table only when the data changes, then you need compare the deleted field value with the inserted field value. After all, the update statement is a delete statement followed by the insert statement.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;So, you need so something like. &lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre class="csharpcode"&gt;INSERT &lt;span class="kwrd"&gt;INTO&lt;/span&gt; AuditTable ( Field )&lt;br /&gt;&lt;span class="kwrd"&gt;SELECT&lt;/span&gt; Deleted.Field&lt;br /&gt;&lt;span class="kwrd"&gt;FROM&lt;/span&gt; Inserted &lt;br /&gt;&lt;span class="kwrd"&gt;INNER&lt;/span&gt; &lt;span class="kwrd"&gt;JOIN&lt;/span&gt; Deleted&lt;br /&gt;&lt;span class="kwrd"&gt;ON&lt;/span&gt; Inserted.Id=Deleted.Id&lt;br /&gt;&lt;span class="kwrd"&gt;WHERE&lt;/span&gt; Inserted.FieldValue&amp;lt;&amp;gt;Deleted.FieldValue&lt;/pre&gt;&lt;br /&gt;&lt;style type="text/css"&gt;&lt;br /&gt;.csharpcode, .csharpcode pre&lt;br /&gt;{&lt;br /&gt;	font-size: small;&lt;br /&gt;	color: black;&lt;br /&gt;	font-family: consolas, "Courier New", courier, monospace;&lt;br /&gt;	background-color: #ffffff;&lt;br /&gt;	/*white-space: pre;*/&lt;br /&gt;}&lt;br /&gt;.csharpcode pre { margin: 0em; }&lt;br /&gt;.csharpcode .rem { color: #008000; }&lt;br /&gt;.csharpcode .kwrd { color: #0000ff; }&lt;br /&gt;.csharpcode .str { color: #006080; }&lt;br /&gt;.csharpcode .op { color: #0000c0; }&lt;br /&gt;.csharpcode .preproc { color: #cc6633; }&lt;br /&gt;.csharpcode .asp { background-color: #ffff00; }&lt;br /&gt;.csharpcode .html { color: #800000; }&lt;br /&gt;.csharpcode .attr { color: #ff0000; }&lt;br /&gt;.csharpcode .alt &lt;br /&gt;{&lt;br /&gt;	background-color: #f4f4f4;&lt;br /&gt;	width: 100%;&lt;br /&gt;	margin: 0em;&lt;br /&gt;}&lt;br /&gt;.csharpcode .lnum { color: #606060; }&lt;/style&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7462882-2425858695103802201?l=gisresearch.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gisresearch.blogspot.com/feeds/2425858695103802201/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7462882&amp;postID=2425858695103802201' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7462882/posts/default/2425858695103802201'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7462882/posts/default/2425858695103802201'/><link rel='alternate' type='text/html' href='http://gisresearch.blogspot.com/2008/12/database-auditing-trigger.html' title='Database auditing trigger.'/><author><name>J.W.</name><uri>http://www.blogger.com/profile/09241601264454722977</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://farm3.static.flickr.com/2116/1856041089_20ef060d43_o.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh3.ggpht.com/_skGtCbVaJ2o/STWVs9n-e8I/AAAAAAAAAlU/9xvZJMwOQCs/s72-c/image_thumb%5B6%5D.png?imgmax=800' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7462882.post-106065341651266056</id><published>2008-09-01T13:29:00.001-04:00</published><updated>2008-09-01T14:36:00.797-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Tools'/><title type='text'>Step into .Net source code.</title><content type='html'>&lt;p&gt;I know it is one of the new features introduced in vs2008, but I didn’t test drive it until lately. Here is steps to set it up. My screenshot is&amp;#160; based on visual studio2008 service pack1, so it may be different with initial installation of visual studio 2008.&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;step 1: Go to Tools –&amp;gt;Options from visual studio, uncheck “Enable Just My Code”, which is set by default, and check “Enable .Net Framework source stepping”. &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;&lt;a href="http://lh3.ggpht.com/jianwei.sun/SLwmYI7KxeI/AAAAAAAAAS8/t01Yuwp2Jz0/s1600-h/DebuggingSettings%5B4%5D.png"&gt;&lt;img style="border-right-width: 0px; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="DebuggingSettings" border="0" alt="DebuggingSettings" src="http://lh6.ggpht.com/jianwei.sun/SLwmYSSYU4I/AAAAAAAAATA/KKf1SeW8WfE/DebuggingSettings_thumb%5B2%5D.png?imgmax=800" width="645" height="379" /&gt;&lt;/a&gt;&amp;#160;&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;step2 :download symbols. I suggest that you click “load symbols from Microsoft symbol servers”, and this will download all the symbol files from microsoft symbol servers at once and cache them locally , so you can avoid keeping fetching the symbol server by uncheck “Search the above locations only when symbols are loaded manually”. &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;&lt;a href="http://lh4.ggpht.com/jianwei.sun/SLwmZN_PlJI/AAAAAAAAATE/6nxB0l8aIw4/s1600-h/loadSymbols%5B6%5D.png"&gt;&lt;img style="border-right-width: 0px; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="loadSymbols" border="0" alt="loadSymbols" src="http://lh3.ggpht.com/jianwei.sun/SLwmZp842EI/AAAAAAAAATI/WH7OREKS8dg/loadSymbols_thumb%5B2%5D.png?imgmax=800" width="645" height="379" /&gt;&lt;/a&gt;&amp;#160; &lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;step3: when you hit the breakpoint, you can choose whether you want to step into the source code. Look at the following , you have two choices, when you choose step into specific, you can step into the set_Text function, when you choose step over properties and operators, you can step over it. &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;&lt;a href="http://lh6.ggpht.com/jianwei.sun/SLwmZ-JiY6I/AAAAAAAAATM/5ZApeL1JICs/s1600-h/stepintoNetCode%5B6%5D.png"&gt;&lt;img style="border-right-width: 0px; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="stepintoNetCode" border="0" alt="stepintoNetCode" src="http://lh3.ggpht.com/jianwei.sun/SLwmasIgXEI/AAAAAAAAATQ/HbNVebV5kug/stepintoNetCode_thumb%5B4%5D.png?imgmax=800" width="644" height="150" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;References:&lt;/p&gt;  &lt;h4&gt;&lt;a href="http://weblogs.asp.net/scottgu/archive/2007/10/03/releasing-the-source-code-for-the-net-framework-libraries.aspx"&gt;Releasing the Source Code for the .NET Framework Libraries&lt;/a&gt;&lt;/h4&gt;  &lt;h4&gt;&lt;a href="http://blogs.msdn.com/sburke/archive/2008/01/16/configuring-visual-studio-to-debug-net-framework-source-code.aspx"&gt;Configuring Visual Studio to Debug .NET Framework Source Code&lt;/a&gt;&lt;/h4&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7462882-106065341651266056?l=gisresearch.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gisresearch.blogspot.com/feeds/106065341651266056/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7462882&amp;postID=106065341651266056' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7462882/posts/default/106065341651266056'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7462882/posts/default/106065341651266056'/><link rel='alternate' type='text/html' href='http://gisresearch.blogspot.com/2008/09/step-into-net-source-code.html' title='Step into .Net source code.'/><author><name>J.W.</name><uri>http://www.blogger.com/profile/09241601264454722977</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://farm3.static.flickr.com/2116/1856041089_20ef060d43_o.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh6.ggpht.com/jianwei.sun/SLwmYSSYU4I/AAAAAAAAATA/KKf1SeW8WfE/s72-c/DebuggingSettings_thumb%5B2%5D.png?imgmax=800' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7462882.post-1196969494114705151</id><published>2008-08-25T20:20:00.001-04:00</published><updated>2008-08-25T20:20:39.376-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Tools'/><title type='text'>Ignore a region in ReSharper</title><content type='html'>&lt;p&gt;I posted this question in ReSharper forum:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;I am sure I am not the only one who has this question.&lt;/p&gt;    &lt;p&gt;When visual studio create some file when I go through wizard, for example, if I create a linq file (*.dbml) , it will create a *.designer.cs. Resharper will generate a lot of warnings for this file. (Total 342 warnings for a single file), Is there any way for me to disable those warnings for the whole file.&lt;/p&gt;    &lt;p&gt;Or , is there any option that I want to disable checking for files with *.designer.cs, thank you very much.&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;Here is the answer I got :&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;I don't know if you can exclude a complete file or wildcard of files although I seem to remember this has been discussed sometime before. In the short term you could try this if you don't know about it already:&lt;/p&gt;    &lt;p&gt;Wrap the code you want to exclude from analysis in a region, say, MyRegion. In RS' options look in the Code Inspection section and select the Settings item. In the Settings you'll see &amp;quot;Generated code regions:&amp;quot;, Click the Add button and add your region name MyRegion as a new item. When you look in the code window you should now see that RS will ignore the contents of the region. I think the name you add is case sensitive. Does that help?&lt;/p&gt;&lt;/blockquote&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7462882-1196969494114705151?l=gisresearch.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gisresearch.blogspot.com/feeds/1196969494114705151/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7462882&amp;postID=1196969494114705151' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7462882/posts/default/1196969494114705151'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7462882/posts/default/1196969494114705151'/><link rel='alternate' type='text/html' href='http://gisresearch.blogspot.com/2008/08/ignore-region-in-resharper.html' title='Ignore a region in ReSharper'/><author><name>J.W.</name><uri>http://www.blogger.com/profile/09241601264454722977</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://farm3.static.flickr.com/2116/1856041089_20ef060d43_o.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7462882.post-8134052828742953755</id><published>2008-08-22T23:10:00.001-04:00</published><updated>2008-08-22T23:10:06.349-04:00</updated><title type='text'>The blogs about windows debugging…</title><content type='html'>&lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/tess/default.aspx"&gt;If broken it is, fix it you should&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/ntdebugging/default.aspx"&gt;Microsoft Advanced Windows Debugging and Troubleshooting&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://www.dumpanalysis.org/blog"&gt;Crash Dump Analysis&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;The first blog is the one of the best blogs I have ever read, Tess got a series of labs which give you a very good start on windbg.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7462882-8134052828742953755?l=gisresearch.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gisresearch.blogspot.com/feeds/8134052828742953755/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7462882&amp;postID=8134052828742953755' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7462882/posts/default/8134052828742953755'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7462882/posts/default/8134052828742953755'/><link rel='alternate' type='text/html' href='http://gisresearch.blogspot.com/2008/08/blogs-about-windows-debugging.html' title='The blogs about windows debugging…'/><author><name>J.W.</name><uri>http://www.blogger.com/profile/09241601264454722977</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://farm3.static.flickr.com/2116/1856041089_20ef060d43_o.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7462882.post-8080686146035438514</id><published>2008-08-06T23:23:00.001-04:00</published><updated>2009-05-07T14:02:55.684-04:00</updated><title type='text'>Convention over configuration( The name is very important in Asp.Net Mvc)</title><content type='html'>&lt;p&gt;When creating mvc application, in order to have the Mvc engine to find your control and view correctly, you have to put the right name. &lt;/p&gt;  &lt;p&gt;For example, if you want to create a Test1 control, then, you have to name your control as Test1Control, and in the Views folder, you have to create a folder created Test1 view folder to put your Test1 related views there. &lt;/p&gt;  &lt;p&gt;This may not sound very natural to the normal asp.net developer, but you just have to do that way…&lt;/p&gt;  &lt;p&gt;Also, to properly map a method in control to one particular view under the Test1 folder, you have to use the same name for the aspx page with the method name.&lt;/p&gt;  &lt;p&gt;In the screenshot, if you have a “Territoris.aspx”, you have to have a Territoris method in the Test1Control class.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh6.ggpht.com/jianwei.sun/SJpqlpqdplI/AAAAAAAAASc/ytto9hDqypU/s1600-h/MVCStructure%5B8%5D.png"&gt;&lt;img style="border-right-width: 0px; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="MVCStructure" border="0" alt="MVCStructure" src="http://lh6.ggpht.com/jianwei.sun/SJpqmbzG82I/AAAAAAAAASg/KvDHbouGw5A/MVCStructure_thumb%5B4%5D.png?imgmax=800" width="333" height="412" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7462882-8080686146035438514?l=gisresearch.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gisresearch.blogspot.com/feeds/8080686146035438514/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7462882&amp;postID=8080686146035438514' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7462882/posts/default/8080686146035438514'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7462882/posts/default/8080686146035438514'/><link rel='alternate' type='text/html' href='http://gisresearch.blogspot.com/2008/08/name-is-very-important-in-aspnet-mvc.html' title='Convention over configuration( The name is very important in Asp.Net Mvc)'/><author><name>J.W.</name><uri>http://www.blogger.com/profile/09241601264454722977</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://farm3.static.flickr.com/2116/1856041089_20ef060d43_o.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh6.ggpht.com/jianwei.sun/SJpqmbzG82I/AAAAAAAAASg/KvDHbouGw5A/s72-c/MVCStructure_thumb%5B4%5D.png?imgmax=800' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7462882.post-8853230633224614514</id><published>2008-08-04T22:52:00.001-04:00</published><updated>2008-08-04T22:52:46.556-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Windows'/><title type='text'>Reading lists on windows.</title><content type='html'>&lt;p&gt;A couple of books I think I need spend more time reading:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://www.amazon.com/Windows-via-C-Pro-Developer/dp/0735624240/ref=pd_bbs_sr_1?ie=UTF8&amp;amp;s=books&amp;amp;qid=1217904492&amp;amp;sr=8-1"&gt;Windows via c/c++&lt;/a&gt;;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://www.amazon.com/Advanced-Debugging-Addison-Wesley-Microsoft-Technology/dp/0321374460/ref=pd_bbs_2?ie=UTF8&amp;amp;s=books&amp;amp;qid=1217904492&amp;amp;sr=8-2"&gt;Advanced windows debugging;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://www.amazon.com/Microsoft-Windows-Internals-4th-Server/dp/0735619174/ref=pd_sim_b_2"&gt;Microsoft windows internals.&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;I have gone through the basic introductions on those books, and all of them are very excellent. I am not sure the order to read them in detail, but probably the first one will be on my top priority just because &lt;a href="http://www.amazon.com/exec/obidos/search-handle-url?_encoding=UTF8&amp;amp;search-type=ss&amp;amp;index=books&amp;amp;field-author=Jeffrey%20Richter"&gt;Jeff&lt;/a&gt; is my favorite author.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7462882-8853230633224614514?l=gisresearch.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gisresearch.blogspot.com/feeds/8853230633224614514/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7462882&amp;postID=8853230633224614514' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7462882/posts/default/8853230633224614514'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7462882/posts/default/8853230633224614514'/><link rel='alternate' type='text/html' href='http://gisresearch.blogspot.com/2008/08/reading-lists-on-windows.html' title='Reading lists on windows.'/><author><name>J.W.</name><uri>http://www.blogger.com/profile/09241601264454722977</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://farm3.static.flickr.com/2116/1856041089_20ef060d43_o.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7462882.post-474413511537058408</id><published>2008-08-01T12:42:00.001-04:00</published><updated>2008-08-01T12:42:11.969-04:00</updated><title type='text'>Good tutorial on three popular .Net mock framework.</title><content type='html'>&lt;p&gt;Here are three popular tutorials on .Net Framework by &lt;a href="http://weblogs.asp.net/stephenwalther/default.aspx"&gt;Stephen Walther&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://weblogs.asp.net/stephenwalther/archive/2008/03/16/tdd-introduction-to-typemock-isolator.aspx"&gt;TypeMock&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;&lt;a href="http://weblogs.asp.net/stephenwalther/archive/2008/06/11/tdd-introduction-to-moq.aspx"&gt;Moq&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://weblogs.asp.net/stephenwalther/archive/2008/03/22/tdd-introduction-to-rhino-mocks.aspx"&gt;Rhino Mock&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Very good tutorials on three major frameworks. &lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7462882-474413511537058408?l=gisresearch.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gisresearch.blogspot.com/feeds/474413511537058408/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7462882&amp;postID=474413511537058408' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7462882/posts/default/474413511537058408'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7462882/posts/default/474413511537058408'/><link rel='alternate' type='text/html' href='http://gisresearch.blogspot.com/2008/08/good-tutorial-on-three-popular-net-mock.html' title='Good tutorial on three popular .Net mock framework.'/><author><name>J.W.</name><uri>http://www.blogger.com/profile/09241601264454722977</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://farm3.static.flickr.com/2116/1856041089_20ef060d43_o.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7462882.post-8173700932184690657</id><published>2008-07-25T23:17:00.001-04:00</published><updated>2008-07-25T23:17:27.686-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Mock'/><category scheme='http://www.blogger.com/atom/ns#' term='.Net'/><category scheme='http://www.blogger.com/atom/ns#' term='TDD'/><title type='text'>.Net mock framework</title><content type='html'>&lt;p&gt;I have been using NUnit/MbUnit/VSTest to develop my tests for a while, but I don’t use mock frameworks too much. I have been reading some blog posts , but didn’t spend too much time digging into those frameworks too much. To effectively use those mock frameworks such as &lt;a href="http://www.ayende.com/projects/rhino-mocks.aspx"&gt;Rhino.Mocks&lt;/a&gt; and &lt;a href="http://code.google.com/p/moq/"&gt;moq&lt;/a&gt; , you have to write your code in a TDD/BDD friendly way. Unfortunately, most of my projects are not designed this way, so I have to manually setup those stubs. &lt;/p&gt;  &lt;p&gt;I started to look into the Asp.Net mvc framework lately and think it’s good opportunity to look into those frameworks because Asp.Net will definitely give those frameworks a push. If you download the &lt;a href="http://haacked.com/archive/2008/05/23/updated-northwind-demo.aspx"&gt;Northwind example&lt;/a&gt; from here, you will find the example uses the moq framework. &lt;/p&gt;  &lt;p&gt;&lt;a href="http://martinfowler.com"&gt;Martin Fowler&lt;/a&gt; wrote a very good article on &lt;a href="http://martinfowler.com/articles/mocksArentStubs.html"&gt;this topic&lt;/a&gt;.&amp;#160; I belong to the classic testers in his definitions.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://weblogs.asp.net/stephenwalther"&gt;Stephen Walther&lt;/a&gt; wrote a very good &lt;a href="http://weblogs.asp.net/stephenwalther/archive/2008/06/11/tdd-introduction-to-moq.aspx"&gt;article&lt;/a&gt; here , and he provided a lot of background information regarding the &lt;a href="http://code.google.com/p/moq/"&gt;Moq&lt;/a&gt; framework. His summary of the previous article is insightful.&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;In this paper, Fowler makes several distinctions. First, he distinguishes a &lt;i&gt;stub&lt;/i&gt; from a &lt;i&gt;mock&lt;/i&gt;. According to Fowler -- who uses Meszaros’ definitions here – stubs “provide canned answers to calls made during the test, usually not responding at all to anything outside what's programmed in for the test.” Mocks, on the other hand, are “objects pre-programmed with expectations which form a specification of the calls they are expected to receive”. &lt;/p&gt;    &lt;p&gt;This distinction between stubs and mocks leads Fowler to distinguish between &lt;i&gt;state verification&lt;/i&gt; and &lt;i&gt;behavior verification&lt;/i&gt;. Stubs are most often used when performing state verification. When performing state verification, you are interested in determining whether a certain condition is true or false at the end of a test. Mocks, on the other hand, are most often used when performing behavior verification. When performing behavior verification, you are interested in how the mock objects interact. For example, you want to know whether a not a certain method was called on one mock object after a method was called on another mock object.&lt;/p&gt;    &lt;p&gt;Fowler makes a final distinction between &lt;i&gt;classical TDD&lt;/i&gt; and &lt;i&gt;mockist TDD&lt;/i&gt;. This final distinction concerns the “philosophy to the way testing and design play together”. A classical TDDer tends to use stubs and state verification. According to Fowler, the “classical TDD style is to use real objects if possible and a double if it's awkward to use the real thing.” A mockist TDDer, on the other hand, almost always uses mocks and behavior verification. A mockist TDDer “will always use a mock for any object with interesting behavior.”&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;I find it very interesting to read &lt;a href="http://www.clariusconsulting.net/blogs/kzu/archive/category/1062.aspx"&gt;the history of moq from its designer kzu&lt;/a&gt;, he created the framework initially because he is not satisfied with the other existing frameworks, however, he has to add a lot of other features into his framework such as VerifyAll. You can find a lot of interesting discussion from the evolving history of moq. Personally, I don’t see moq provides much more than Rhino Mocks. I probably reference both in my project.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7462882-8173700932184690657?l=gisresearch.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gisresearch.blogspot.com/feeds/8173700932184690657/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7462882&amp;postID=8173700932184690657' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7462882/posts/default/8173700932184690657'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7462882/posts/default/8173700932184690657'/><link rel='alternate' type='text/html' href='http://gisresearch.blogspot.com/2008/07/net-mock-framework.html' title='.Net mock framework'/><author><name>J.W.</name><uri>http://www.blogger.com/profile/09241601264454722977</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://farm3.static.flickr.com/2116/1856041089_20ef060d43_o.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7462882.post-5261089479370773282</id><published>2008-07-17T16:20:00.001-04:00</published><updated>2008-07-17T16:20:55.527-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Windows'/><category scheme='http://www.blogger.com/atom/ns#' term='C++'/><title type='text'>Unicode and ANSI function in CRT</title><content type='html'>&lt;h4&gt;&lt;a name="68"&gt;&lt;/a&gt;From the book &lt;a href="http://www.amazon.com/Windows-via-C-Pro-Developer/dp/0735624240"&gt;Windows via C/C++&lt;/a&gt;&lt;/h4&gt;  &lt;h4&gt;&amp;#160;&lt;/h4&gt;  &lt;h4&gt;Unicode and ANSI Functions in the C Run-Time Library&lt;/h4&gt;  &lt;p&gt;Like the Windows functions, the C run-time library offers one set of functions to manipulate ANSI characters and strings and another set of functions to manipulate Unicode characters and strings. However, unlike Windows, the ANSI functions do the work; they do not translate the strings to Unicode and then call the Unicode version of the functions internally. And, of course, the Unicode versions do the work themselves too; they do not internally call the ANSI versions.&lt;/p&gt;  &lt;p&gt;An example of a C run-time function that returns the length of an ANSI string is &lt;b&gt;strlen&lt;/b&gt;, and an example of an equivalent C run-time function that returns the length of a Unicode string is &lt;b&gt;wcslen&lt;/b&gt;.&lt;/p&gt;  &lt;p&gt;&lt;a name="69"&gt;&lt;/a&gt;&lt;a name="IDX-181C4AB577-C32E-4A16-BF0F-07F3124E103E"&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Both of these functions are prototyped in String.h. To write source code that can be compiled for either ANSI or Unicode, you must also include TChar.h, which defines the following macro:&lt;/p&gt;  &lt;pre&gt;#ifdef _UNICODE&lt;br /&gt;#define _tcslen     wcslen&lt;br /&gt;#else&lt;br /&gt;#define _tcslen     strlen&lt;br /&gt;#endif&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;Now, in your code, you should call &lt;b&gt;_tcslen&lt;/b&gt;. If &lt;b&gt;_UNICODE&lt;/b&gt; is defined, it expands to &lt;b&gt;wcslen&lt;/b&gt;; otherwise, it expands to &lt;b&gt;strlen&lt;/b&gt;. By default, when you create a new C++ project in Visual Studio, &lt;b&gt;_UNICODE&lt;/b&gt; is defined (just like &lt;b&gt;UNICODE&lt;/b&gt; is defined). &lt;strong&gt;&lt;font color="#ff0000"&gt;The C run-time library always prefixes identifiers that are not part of the C++ standard with underscores, while the Windows team does not do this. So, in your applications you'll want to make sure that both UNICODE and _UNICODE are defined or that neither is defined&lt;/font&gt;&lt;/strong&gt;. Appendix A, &amp;quot;The Build Environment,&amp;quot; will describe the details of the CmnHdr.h header file used by all the code samples of this book to avoid this kind of problem.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7462882-5261089479370773282?l=gisresearch.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gisresearch.blogspot.com/feeds/5261089479370773282/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7462882&amp;postID=5261089479370773282' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7462882/posts/default/5261089479370773282'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7462882/posts/default/5261089479370773282'/><link rel='alternate' type='text/html' href='http://gisresearch.blogspot.com/2008/07/unicode-and-ansi-function-in-crt.html' title='Unicode and ANSI function in CRT'/><author><name>J.W.</name><uri>http://www.blogger.com/profile/09241601264454722977</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://farm3.static.flickr.com/2116/1856041089_20ef060d43_o.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7462882.post-3929153260221426633</id><published>2008-07-16T19:39:00.001-04:00</published><updated>2008-07-16T19:40:30.148-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='C++'/><title type='text'>A concept which confuses me for a while…</title><content type='html'>&lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;How do you organize c++ header file with template. Here is a good explanation from &lt;a href="http://www.amazon.com/Templates-Complete-Guide-David-Vandevoorde/dp/0201734842"&gt;C++ Templates: The Complete Guide.&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;h5&gt;6.1 The Inclusion Model&lt;/h5&gt;  &lt;p&gt;There are several ways to organize template source code. &lt;font color="#ff0000"&gt;&lt;strong&gt;This section presents the most popular approach as of the time of this writing: the inclusion model.&lt;/strong&gt;&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;a name="ch06lev2sec1"&gt;&lt;/a&gt;&lt;/p&gt;  &lt;h6&gt;6.1.1 Linker Errors&lt;/h6&gt;  &lt;p&gt;Most C and C++ programmers organize their nontemplate code largely as follows:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;     &lt;p&gt;Classes and other types are entirely placed in header files. Typically, this is a file with a &lt;tt&gt;.hpp&lt;/tt&gt; (or &lt;tt&gt;.H&lt;/tt&gt;, &lt;tt&gt;.h&lt;/tt&gt;, &lt;tt&gt;.hh&lt;/tt&gt;, &lt;tt&gt;.hxx&lt;/tt&gt;) filename extension.&lt;/p&gt;   &lt;/li&gt;    &lt;li&gt;     &lt;p&gt;For global variables and (noninline) functions, only a declaration is put in a header file, and the definition goes into a so-called dot-C file. Typically, this is a file with a &lt;tt&gt;.cpp&lt;/tt&gt; (or &lt;tt&gt;.C&lt;/tt&gt;, &lt;tt&gt;.c&lt;/tt&gt;, &lt;tt&gt;.cc&lt;/tt&gt;, or &lt;tt&gt;.hxx&lt;/tt&gt;) filename extension.&lt;/p&gt;   &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;This works well: It makes the needed type definition easily available throughout the program and avoids duplicate definition errors on variables and functions from the linker.&lt;/p&gt;  &lt;p&gt;With these conventions in mind, a common error about which beginning template programmers complain is illustrated by the following (erroneous) little program. As usual for &amp;quot;ordinary code,&amp;quot; we declare the template in a header file:&lt;/p&gt;  &lt;pre&gt;// basics/myfirst.hpp &lt;br /&gt;&lt;br /&gt;#ifndef MYFIRST_HPP &lt;br /&gt;#define MYFIRST_HPP &lt;br /&gt;&lt;br /&gt;// declaration of template &lt;br /&gt;template &amp;lt;typename T&amp;gt; &lt;br /&gt;void print_typeof (T const&amp;amp;); &lt;br /&gt;&lt;br /&gt;#endif // MYFIRST_HPP &lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;tt&gt;print_typeof()&lt;/tt&gt; is the declaration of a simple auxiliary function that prints some type information. The implementation of the function is placed in a dot-C file:&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;// basics/myfirst.cpp &lt;br /&gt;&lt;br /&gt;#include &amp;lt;iostream&amp;gt; &lt;br /&gt;#include &amp;lt;typeinfo&amp;gt; &lt;br /&gt;#include &amp;quot;myfirst.hpp&amp;quot; &lt;br /&gt;&lt;br /&gt;// implementation/definition of template &lt;br /&gt;template &amp;lt;typename T&amp;gt; &lt;br /&gt;void print_typeof (T const&amp;amp; x) &lt;br /&gt;{ &lt;br /&gt;    std::cout &amp;lt;&amp;lt; typeid(x).name() &amp;lt;&amp;lt; std::endl; &lt;br /&gt;} &lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;The example uses the &lt;tt&gt;typeid&lt;/tt&gt; operator to print a string that describes the type of the expression passed to it (see &lt;a href="helpexplorer:///0201734842_ch05lev1sec6.html#ch05lev1sec6"&gt;Section 5.6&lt;/a&gt; on page 58).&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;Finally, we use the template in another dot-C file, into which our template declaration is &lt;tt&gt;#included:&lt;/tt&gt;&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;// basics/myfirstmain.cpp &lt;br /&gt;&lt;br /&gt;#include &amp;quot;myfirst.hpp&amp;quot; &lt;br /&gt;&lt;br /&gt;// use of the template &lt;br /&gt;int main() &lt;br /&gt;{ &lt;br /&gt;    double ice = 3.0; &lt;br /&gt;    print_typeof(ice);  // call function template for type double &lt;br /&gt;} &lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;A C++ compiler will most likely accept this program without any problems, but the linker will probably report an error, implying that there is no definition of the function &lt;tt&gt;print_typeof()&lt;/tt&gt;.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;The reason for this error is that the definition of the function template &lt;tt&gt;print_typeof()&lt;/tt&gt; has not been instantiated. In order for a template to be instantiated, the compiler must know which definition should be instantiated and for what template arguments it should be instantiated. Unfortunately, in the previous example, these two pieces of information are in files that are compiled separately. Therefore, when our compiler sees the call to &lt;tt&gt;print_typeof()&lt;/tt&gt; but has no definition in sight to instantiate this function for &lt;tt&gt;double&lt;/tt&gt;, it just assumes that such a definition is provided elsewhere and creates a reference (for the linker to resolve) to that definition. On the other hand, when the compiler processes the file &lt;tt&gt;myfirst.cpp&lt;/tt&gt;, it has no indication at that point that it must instantiate the template definition it contains for specific arguments.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;a name="ch06lev2sec2"&gt;&lt;/a&gt;&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;h6&gt;6.1.2 Templates in Header Files&lt;/h6&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;The common solution to the previous problem is to use the same approach that we would take with macros or with inline functions: We include the definitions of a template in the header file that declares that template. For our example, we can do this by adding&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;#include &amp;quot;myfirst.cpp&amp;quot; &lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;at the end of &lt;tt&gt;myfirst.hpp&lt;/tt&gt; or by including &lt;tt&gt;myfirst.cpp&lt;/tt&gt; in every dot-C file that uses the template. A third way, of course, is to do away entirely with &lt;tt&gt;myfirst.cpp&lt;/tt&gt; and rewrite &lt;tt&gt;myfirst.hpp&lt;/tt&gt; so that it contains all template declarations and template definitions:&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;// basics/myfirst2.hpp &lt;br /&gt;&lt;br /&gt;#ifndef MYFIRST_HPP &lt;br /&gt;#define MYFIRST_HPP &lt;br /&gt;&lt;br /&gt;#include &amp;lt;iostream&amp;gt; &lt;br /&gt;#include &amp;lt;typeinfo&amp;gt; &lt;br /&gt;&lt;br /&gt;// declaration of template &lt;br /&gt;template &amp;lt;typename T&amp;gt; &lt;br /&gt;void print_typeof (T const&amp;amp;); &lt;br /&gt;&lt;br /&gt;// implementation/definition of template &lt;br /&gt;template &amp;lt;typename T&amp;gt; &lt;br /&gt;void print_typeof (T const&amp;amp; x) &lt;br /&gt;{ &lt;br /&gt;    std::cout &amp;lt;&amp;lt; typeid(x).name() &amp;lt;&amp;lt; std::endl; &lt;br /&gt;} &lt;br /&gt;&lt;br /&gt;#endif // MYFIRST_HPP &lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;This way of organizing templates is called the inclusion model. With this in place, you should find that our program now correctly compiles, links, and executes.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;There are a few observations we can make at this point. The most notable is that this approach has considerably increased the cost of including the header file &lt;tt&gt;myfirst.hpp&lt;/tt&gt;. In this example, the cost is not the result of the size of the template definition itself, but the result of the fact that we must also include the headers used by the definition of our template—in this case &lt;tt&gt;&amp;lt;iostream&amp;gt;&lt;/tt&gt; and &lt;tt&gt;&amp;lt;typeinfo&amp;gt;&lt;/tt&gt;. You may find that this amounts to tens of thousands of lines of code because headers like &lt;tt&gt;&amp;lt;iostream&amp;gt;&lt;/tt&gt; contain similar template definitions.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;This is a real problem in practice because it considerably increases the time needed by the compiler to compile significant programs. We will therefore examine some possible ways to approach this problem in upcoming sections. However, real-world programs quickly end up taking hours to compile and link (we have been involved in situations in which it literally took days to build a program completely from its source code).&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;strong&gt;&lt;font color="#ff0000"&gt;Despite this build-time issue, we do recommend following this inclusion model to organize your templates when possible. We examine two alternatives, but in our opinion their engineering deficiencies are more serious than the build-time issue discussed here. They may have other advantages not directly related to the engineering aspects of software development, however.&lt;/font&gt;&lt;/strong&gt;&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;Another (more subtle) observation about the inclusion approach is that noninline function templates are distinct from inline functions and macros in an important way: They are not expanded at the call site. Instead, when they are instantiated, they create a new copy of a function. Because this is an automatic process, a compiler could end up creating two copies in two different files, and some linkers could issue errors when they find two distinct definitions for the same function. In theory, this should not be a concern of ours: It is a problem for the C++ compilation system to accommodate. In practice, things work well most of the time, and we don't need to deal with this issue at all. For large projects that create their own library of code, however, problems occasionally show up. A discussion of instantiation schemes in &lt;a href="helpexplorer:///0201734842_ch10.html#ch10"&gt;Chapter 10&lt;/a&gt; and a close study of the documentation that came with the C++ translation system (compiler) should help address these problems.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;Finally, we need to point out that what applies to the ordinary function template in our example also applies to member functions and static data members of class templates, as well as to member function templates.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7462882-3929153260221426633?l=gisresearch.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gisresearch.blogspot.com/feeds/3929153260221426633/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7462882&amp;postID=3929153260221426633' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7462882/posts/default/3929153260221426633'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7462882/posts/default/3929153260221426633'/><link rel='alternate' type='text/html' href='http://gisresearch.blogspot.com/2008/07/concept-which-confuses-me-for-while.html' title='A concept which confuses me for a while…'/><author><name>J.W.</name><uri>http://www.blogger.com/profile/09241601264454722977</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://farm3.static.flickr.com/2116/1856041089_20ef060d43_o.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7462882.post-3226285361264747970</id><published>2008-07-12T09:55:00.001-04:00</published><updated>2008-07-12T10:21:23.828-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='C++'/><title type='text'>Going back to basic – should 0 or 1 be returned from function..</title><content type='html'>&lt;p&gt;&lt;/p&gt;  &lt;p&gt;Here is a very &lt;em&gt;&lt;a href="http://www.fungileo.com/?p=7"&gt;good article&lt;/a&gt;&lt;/em&gt; about this topic.&lt;/p&gt;  &lt;p&gt;The basics concern whether you should return 0 as success or 1 as success. In a main function , normally, you will return 0 as success and other variables as failure codes. However, when you try to map to boolean code, 0 is false, and non-0 is success, and that’s the extra level of confusion. So, if you do want to return boolean state as the function return value, it’s best to use bool, &lt;strong&gt;NOT&lt;/strong&gt; integer.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7462882-3226285361264747970?l=gisresearch.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gisresearch.blogspot.com/feeds/3226285361264747970/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7462882&amp;postID=3226285361264747970' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7462882/posts/default/3226285361264747970'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7462882/posts/default/3226285361264747970'/><link rel='alternate' type='text/html' href='http://gisresearch.blogspot.com/2008/07/going-back-to-basic-should-0-or-1-be.html' title='Going back to basic – should 0 or 1 be returned from function..'/><author><name>J.W.</name><uri>http://www.blogger.com/profile/09241601264454722977</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://farm3.static.flickr.com/2116/1856041089_20ef060d43_o.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7462882.post-1594255324523618059</id><published>2008-07-08T23:04:00.001-04:00</published><updated>2008-07-08T23:04:01.120-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Tools'/><title type='text'>Google code</title><content type='html'>&lt;p&gt;I have been using google code to store some of my practice projects for a while, mostly to store the source files. I use the &lt;a href="http://tortoisesvn.tigris.org/"&gt;TortoiseSVN&lt;/a&gt; to compare the different revisions of the files. I spent a little bit time to check some functions provide the web user interface, and was very impressed with the changes. &lt;/p&gt;  &lt;p&gt;Here is the screenshot of the feature..&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh6.ggpht.com/jianwei.sun/SHQqnQYk23I/AAAAAAAAARk/sA5cImRw7H4/s1600-h/googlecode%5B5%5D.png"&gt;&lt;img title="googlecode" style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="312" alt="googlecode" src="http://lh5.ggpht.com/jianwei.sun/SHQqoB2AgbI/AAAAAAAAARo/ZvIW0UCsEaY/googlecode_thumb%5B3%5D.png?imgmax=800" width="644" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;I haven’t really checked into the other alternatives such as &lt;a href="http://www.codeplex.com/"&gt;CodePlex&lt;/a&gt; and &lt;a href="http://sourceforge.net/"&gt;SourceForge&lt;/a&gt; , but I have to say the google code features are very impressive.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7462882-1594255324523618059?l=gisresearch.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gisresearch.blogspot.com/feeds/1594255324523618059/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7462882&amp;postID=1594255324523618059' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7462882/posts/default/1594255324523618059'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7462882/posts/default/1594255324523618059'/><link rel='alternate' type='text/html' href='http://gisresearch.blogspot.com/2008/07/google-code.html' title='Google code'/><author><name>J.W.</name><uri>http://www.blogger.com/profile/09241601264454722977</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://farm3.static.flickr.com/2116/1856041089_20ef060d43_o.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh5.ggpht.com/jianwei.sun/SHQqoB2AgbI/AAAAAAAAARo/ZvIW0UCsEaY/s72-c/googlecode_thumb%5B3%5D.png?imgmax=800' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7462882.post-5961356336939627467</id><published>2008-06-29T21:40:00.000-04:00</published><updated>2008-06-29T21:41:15.917-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Tools'/><category scheme='http://www.blogger.com/atom/ns#' term='C++'/><title type='text'>Eclipse CDT</title><content type='html'>&lt;p&gt;I am spending some time to set up the eclipse CDT this weekend since I want to review some of my c++ knowledge. I have been using visual studio c++ for long time and I really enjoyed using it. The problem with visual c++ is that it added a lot of extensions for you, and you will easily program in Microsoft c++, NOT the really ANSI c++. &lt;/p&gt;  &lt;p&gt;It did take some time for me to set up the environment. Admittedly, the setup process is not as easy as the visual studio one – click process. And &lt;a href="http://www.eclipse.org/cdt/"&gt;the online documentation&lt;/a&gt; is not very accurate or up to date. A much better &lt;a href="http://max.berger.name/howto/cdt/ar01s03.jsp"&gt;step by step&lt;/a&gt; setup process can be found here.&lt;/p&gt;  &lt;p&gt;Overall, the experience is pretty positive, I can start to write some simple c++ program and compile it. &lt;/p&gt;  &lt;p&gt;One thing that still confuses me is the debugger continues giving me this message &lt;font color="#ff0000"&gt;mi_cmd_var_create: unable to create variable object&lt;/font&gt; whenever I start to debug. I posted it to the cdt newsgroup, hopefully, somebody could help me on this.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7462882-5961356336939627467?l=gisresearch.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gisresearch.blogspot.com/feeds/5961356336939627467/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7462882&amp;postID=5961356336939627467' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7462882/posts/default/5961356336939627467'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7462882/posts/default/5961356336939627467'/><link rel='alternate' type='text/html' href='http://gisresearch.blogspot.com/2008/06/eclipse-cdt.html' title='Eclipse CDT'/><author><name>J.W.</name><uri>http://www.blogger.com/profile/09241601264454722977</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://farm3.static.flickr.com/2116/1856041089_20ef060d43_o.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7462882.post-2907068847602402331</id><published>2008-06-22T16:26:00.001-04:00</published><updated>2008-06-22T16:26:37.426-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Tools'/><title type='text'>Ignore folders in svn</title><content type='html'>&lt;p&gt;This is copied from the helper file:&lt;/p&gt; &lt;p&gt;To ignore all &lt;code&gt;CVS&lt;/code&gt; folders you should either specify a pattern of &lt;code&gt;*CVS&lt;/code&gt; or better, the pair &lt;code&gt;CVS */CVS&lt;/code&gt;. The first option works, but would also exclude something called &lt;code&gt;ThisIsNotCVS&lt;/code&gt;. Using &lt;code&gt;*/CVS&lt;/code&gt; alone will not work on an immediate child &lt;code&gt;CVS&lt;/code&gt; folder, and &lt;code&gt;CVS&lt;/code&gt; alone will not work on sub-folders.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7462882-2907068847602402331?l=gisresearch.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gisresearch.blogspot.com/feeds/2907068847602402331/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7462882&amp;postID=2907068847602402331' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7462882/posts/default/2907068847602402331'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7462882/posts/default/2907068847602402331'/><link rel='alternate' type='text/html' href='http://gisresearch.blogspot.com/2008/06/ignore-folders-in-svn.html' title='Ignore folders in svn'/><author><name>J.W.</name><uri>http://www.blogger.com/profile/09241601264454722977</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://farm3.static.flickr.com/2116/1856041089_20ef060d43_o.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7462882.post-2436982895204961247</id><published>2008-05-20T12:57:00.001-04:00</published><updated>2008-05-20T12:57:37.642-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Asp.Net'/><category scheme='http://www.blogger.com/atom/ns#' term='Visual Studio'/><category scheme='http://www.blogger.com/atom/ns#' term='TDD'/><title type='text'>Web Testing, Load Testing, Unit Testing...</title><content type='html'>&lt;p&gt;I understand that unit testing should cover most of scenarios if an application is nicely designed with some pro-unit testing framework, namely MVC pattern. In .Net world, those unit testing friendly frameworks include &lt;em&gt;&lt;a href="http://weblogs.asp.net/scottgu/archive/2007/10/14/asp-net-mvc-framework.aspx"&gt;Asp.Net MVC&lt;/a&gt;&lt;/em&gt;, and &lt;a href="http://www.castleproject.org/"&gt;Castle Project&lt;/a&gt;. But a lot of times, an application has already been designed and put into the production, you don't have time, money, and energy to re-write those anti-unit testing applications based on unit-testing friendly framework.&amp;#160; Mostly importantly, business users don't understand why you want to rewrite an application just because you want to be able to unit testing it, they just need a workable application, and don't care too much about the back end unit testing which is an essential part of the whole project.&lt;/p&gt;  &lt;p&gt;I am working on an application which is heavily depend on &lt;a href="http://www.lhotka.net/cslanet/Default.aspx"&gt;CSLA.Net&lt;/a&gt; framework, which is a very impressive framework. However, the framework is not very TDD friendly, and check out &lt;a href="http://forums.lhotka.net/forums/thread/1136.aspx"&gt;some discussions&lt;/a&gt; in this post. I started to look for some other alternatives which can automate the testing process, and the visual studio team system had &lt;a href="http://msdn.microsoft.com/en-us/teamsystem/aa718941.aspx"&gt;an edition for software testers&lt;/a&gt; starting from Visual studio 2005. But honestly, I won't recommend using it unless you have the VS2008 version. The biggest limitation of VS2005 test version is that it doesn't support Ajax testing natively, and you have to rely on &lt;em&gt;&lt;a href="http://www.fiddlertool.com/fiddler/"&gt;fiddler tool&lt;/a&gt;&lt;/em&gt; to record the testing. VS 2005 test version cannot detect dynamic parameter very well, and I have big trouble to get those viewstate related variables work. VS 2008 version definitely did a lot of improvements in those areas, although it's not free of bugs either. Check out &lt;a href="http://blogs.msdn.com/edglas/archive/2007/12/02/web-test-authoring-and-debugging-techniques-for-vs-2008.aspx"&gt;an excellent post on web test in&lt;/a&gt; visual studio 2008 here.&lt;/p&gt;  &lt;p&gt;A couple of roadblocks I have in working on the automating tests are:&lt;/p&gt;  &lt;p&gt;1. You have to turn page validation off and view state check off. You probably want to turn it back in production environment.&lt;/p&gt;  &lt;div style="border-right: gray 1px solid; padding-right: 4px; border-top: gray 1px solid; padding-left: 4px; font-size: 8pt; padding-bottom: 4px; margin: 20px 0px 10px; overflow: auto; border-left: gray 1px solid; width: 97.5%; cursor: text; max-height: 200px; line-height: 12pt; padding-top: 4px; border-bottom: gray 1px solid; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; background-color: #f4f4f4"&gt;&amp;lt;pages theme=&amp;quot;Main&amp;quot; enableEventValidation=&amp;quot;false&amp;quot; enableViewStateMac=&amp;quot;false&amp;quot; &amp;gt;&lt;/div&gt;  &lt;p&gt;2. You may need to hard code a machine key if you want to port the test to different sites. In our cases, we recorded the tests on a test website, but we also want to run it on stage site too.&lt;/p&gt;  &lt;div style="border-right: gray 1px solid; padding-right: 4px; border-top: gray 1px solid; padding-left: 4px; font-size: 8pt; padding-bottom: 4px; margin: 20px 0px 10px; overflow: auto; border-left: gray 1px solid; width: 88.3%; cursor: text; max-height: 200px; line-height: 12pt; padding-top: 4px; border-bottom: gray 1px solid; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; height: 124px; background-color: #f4f4f4"&gt;   &lt;div style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;     &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   1:&lt;/span&gt; &amp;lt;machineKey&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   2:&lt;/span&gt;     validationKey=&lt;span style="color: #006080"&gt;&amp;quot;9A1F64F585E06F97562808D96860AC9E3DA5F231EA34B42E8C98AE02B52EAF33CF7EF24C618F7F391756974090458C9740BE1007E6F898161C39B863A7E46C3D&amp;quot;&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   3:&lt;/span&gt;     decryptionKey=&lt;span style="color: #006080"&gt;&amp;quot;376909E1031E5AA520AAE33B554ACACCE0CAEA2BA0B142FB3050D814059398CB&amp;quot;&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   4:&lt;/span&gt;     validation=&lt;span style="color: #006080"&gt;&amp;quot;SHA1&amp;quot;&lt;/span&gt; decryption=&lt;span style="color: #006080"&gt;&amp;quot;AES&amp;quot;&lt;/span&gt;/&amp;gt;  &lt;/pre&gt;&lt;br /&gt;  &lt;/div&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;3. Some post parameters are promoted as dynamic parameters incorrectly, watch out those if you need manually correct those.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;4. Check out this &lt;a href="http://www.codeplex.com/UKVSTS/Wiki/View.aspx?title=UKVSTS%20Web%20Test%20Plug%20In&amp;amp;referringTitle=Home"&gt;web test plug in&lt;/a&gt; if you want to use some .Net functions in your test.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;Sometimes, you want to create set up some specific pre-testing condition, and tear down those values added to your database in your testing, you can create a plug in to do this work.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;a href="http://lh6.ggpht.com/jianwei.sun/SDMC-fSh0CI/AAAAAAAAAPE/Or4ccPzQQI0/s1600-h/WebTestPlugIn%5B7%5D.png"&gt;&lt;img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="223" alt="WebTestPlugIn" src="http://lh4.ggpht.com/jianwei.sun/SDMC-_Sh0DI/AAAAAAAAAPM/_0EwrJVJCT8/WebTestPlugIn_thumb%5B5%5D.png?imgmax=800" width="795" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;In our projects, in PreWebTest, we create an object in the database which we need run our test on, and in PostWebTest, we delete this object. It works very well for our situation. We run those tests every day , and those green pass icons definitely make our life much easier.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&amp;#160;&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;a href="http://lh3.ggpht.com/jianwei.sun/SDMC_vSh0EI/AAAAAAAAAPU/r143ogpit18/s1600-h/TestResults%5B6%5D.png"&gt;&lt;img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="474" alt="TestResults" src="http://lh5.ggpht.com/jianwei.sun/SDMDAPSh0FI/AAAAAAAAAPc/dM-dnI3sx9Q/TestResults_thumb%5B4%5D.png?imgmax=800" width="644" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7462882-2436982895204961247?l=gisresearch.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gisresearch.blogspot.com/feeds/2436982895204961247/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7462882&amp;postID=2436982895204961247' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7462882/posts/default/2436982895204961247'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7462882/posts/default/2436982895204961247'/><link rel='alternate' type='text/html' href='http://gisresearch.blogspot.com/2008/05/web-testing-load-testing-unit-testing.html' title='Web Testing, Load Testing, Unit Testing...'/><author><name>J.W.</name><uri>http://www.blogger.com/profile/09241601264454722977</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://farm3.static.flickr.com/2116/1856041089_20ef060d43_o.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh4.ggpht.com/jianwei.sun/SDMC-_Sh0DI/AAAAAAAAAPM/_0EwrJVJCT8/s72-c/WebTestPlugIn_thumb%5B5%5D.png?imgmax=800' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7462882.post-5866159977948614063</id><published>2008-05-16T13:51:00.001-04:00</published><updated>2008-05-20T12:58:52.713-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Asp.Net'/><category scheme='http://www.blogger.com/atom/ns#' term='.Net'/><title type='text'>Setting up IIS7 on windows vista</title><content type='html'>&lt;p&gt;I spent quite some time to figure this out, the process is not as easy or straightfard as&amp;#160; the process to set up II6 on windows xp.&lt;/p&gt;  &lt;p&gt;At firstly, I just go ahead and turn on the Internet Information Services and think that's all I need do.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh5.ggpht.com/jianwei.sun/SC3JgvShz8I/AAAAAAAAAPk/BpeOgqu8Ak4/s1600-h/CropperCapture%5B31%5D%5B2%5D.png"&gt;&lt;img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="711" alt="CropperCapture[31]" src="http://lh3.ggpht.com/jianwei.sun/SC3JhPShz9I/AAAAAAAAAPo/2KX93LIGnMU/CropperCapture%5B31%5D_thumb%5B2%5D.png?imgmax=800" width="701" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;But when I tried to open up the page, I got this error.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh3.ggpht.com/jianwei.sun/SC3JiPShz-I/AAAAAAAAAPs/ckGHora9vZE/s1600-h/CropperCapture%5B32%5D.png"&gt;&lt;img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="630" alt="CropperCapture[32]" src="http://lh5.ggpht.com/jianwei.sun/SC3JivShz_I/AAAAAAAAAPw/mBJ463d81zk/CropperCapture%5B32%5D_thumb.png?imgmax=800" width="865" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;The trick is that under the &amp;quot;Internet Information Services&amp;quot;, there are a lot of other settings you need check.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh3.ggpht.com/jianwei.sun/SC3JjPSh0AI/AAAAAAAAAP0/5QXSM7W0yPM/s1600-h/CropperCapture%5B33%5D.png"&gt;&lt;img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="701" alt="CropperCapture[33]" src="http://lh5.ggpht.com/jianwei.sun/SC3JjvSh0BI/AAAAAAAAAP4/e87MF2dg9dw/CropperCapture%5B33%5D_thumb.png?imgmax=800" width="692" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;You have to enable those settings as well.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7462882-5866159977948614063?l=gisresearch.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gisresearch.blogspot.com/feeds/5866159977948614063/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7462882&amp;postID=5866159977948614063' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7462882/posts/default/5866159977948614063'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7462882/posts/default/5866159977948614063'/><link rel='alternate' type='text/html' href='http://gisresearch.blogspot.com/2008/05/setting-up-iis7-on-windows-vista.html' title='Setting up IIS7 on windows vista'/><author><name>J.W.</name><uri>http://www.blogger.com/profile/09241601264454722977</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://farm3.static.flickr.com/2116/1856041089_20ef060d43_o.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh3.ggpht.com/jianwei.sun/SC3JhPShz9I/AAAAAAAAAPo/2KX93LIGnMU/s72-c/CropperCapture%5B31%5D_thumb%5B2%5D.png?imgmax=800' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7462882.post-2422237234111461607</id><published>2008-05-16T11:24:00.001-04:00</published><updated>2008-05-16T11:25:19.658-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Tools'/><category scheme='http://www.blogger.com/atom/ns#' term='Visual Studio'/><title type='text'>Install the source server for TFS Building.</title><content type='html'>&lt;p&gt;In the book &lt;a href="http://www.advancedwindowsdebugging.com/"&gt;&amp;quot;Advanced windows debugging&amp;quot;,&lt;/a&gt; a detailed process on how to set up source server for the visual sourcesafe building. But most people today are now using the Team system to mange the code and build system, and here is an excellent link about &amp;quot;&lt;a href="http://jelle.druyts.net/2007/12/09/SettingUpSourceServerForTFSBuilds.aspx"&gt;Setting up the Source Server for TFS builds&lt;/a&gt;&amp;quot;. &lt;/p&gt;  &lt;p&gt;Good stuff.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7462882-2422237234111461607?l=gisresearch.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gisresearch.blogspot.com/feeds/2422237234111461607/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7462882&amp;postID=2422237234111461607' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7462882/posts/default/2422237234111461607'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7462882/posts/default/2422237234111461607'/><link rel='alternate' type='text/html' href='http://gisresearch.blogspot.com/2008/05/install-source-server-for-tfs-building.html' title='Install the source server for TFS Building.'/><author><name>J.W.</name><uri>http://www.blogger.com/profile/09241601264454722977</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://farm3.static.flickr.com/2116/1856041089_20ef060d43_o.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7462882.post-2045908806360178174</id><published>2008-04-07T13:32:00.001-04:00</published><updated>2008-04-07T13:32:17.598-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Tools'/><category scheme='http://www.blogger.com/atom/ns#' term='Visual Studio'/><title type='text'>Clear workspace in TFS</title><content type='html'>&lt;p&gt;We have a couple of contractors who worked on our project before left. When they left, they didn't check in all the codes on their machine. I work on deleting some of the projects which have files checked out by them and are not used by anybody else now. I cannot do that because the TFS complains that some files were checked out by those contractors.&lt;/p&gt;  &lt;p&gt;I googled around and found a simple solution in MSDN, the easiest way is to delete the workspace altogether:&lt;/p&gt;  &lt;p&gt;Here is the exact command: tf worksapce /delete /server:servername workspacename[;workspaceowner].&lt;/p&gt;  &lt;p&gt;The workspacename is normally the machine name.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://msdn2.microsoft.com/en-us/library/y901w7se(VS.80).aspx"&gt;MSDN link is here.&lt;/a&gt;&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7462882-2045908806360178174?l=gisresearch.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gisresearch.blogspot.com/feeds/2045908806360178174/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7462882&amp;postID=2045908806360178174' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7462882/posts/default/2045908806360178174'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7462882/posts/default/2045908806360178174'/><link rel='alternate' type='text/html' href='http://gisresearch.blogspot.com/2008/04/clear-workspace-in-tfs.html' title='Clear workspace in TFS'/><author><name>J.W.</name><uri>http://www.blogger.com/profile/09241601264454722977</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://farm3.static.flickr.com/2116/1856041089_20ef060d43_o.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7462882.post-2506414875358556506</id><published>2007-12-14T22:30:00.001-05:00</published><updated>2007-12-14T22:30:20.087-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='SQL'/><title type='text'>Enable sql cache dependency in sql 2005</title><content type='html'>&lt;p&gt;Here is a post about how to enable sql cache dependency in sql 2005 &lt;a title="http://davidhayden.com/blog/dave/archive/2006/04/29/2929.aspx" href="http://davidhayden.com/blog/dave/archive/2006/04/29/2929.aspx"&gt;http://davidhayden.com/blog/dave/archive/2006/04/29/2929.aspx&lt;/a&gt;&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7462882-2506414875358556506?l=gisresearch.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gisresearch.blogspot.com/feeds/2506414875358556506/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7462882&amp;postID=2506414875358556506' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7462882/posts/default/2506414875358556506'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7462882/posts/default/2506414875358556506'/><link rel='alternate' type='text/html' href='http://gisresearch.blogspot.com/2007/12/enable-sql-cache-dependency-in-sql-2005.html' title='Enable sql cache dependency in sql 2005'/><author><name>J.W.</name><uri>http://www.blogger.com/profile/09241601264454722977</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://farm3.static.flickr.com/2116/1856041089_20ef060d43_o.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7462882.post-5641410586659187587</id><published>2007-12-14T11:59:00.001-05:00</published><updated>2009-01-23T21:57:30.287-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='CSS'/><title type='text'>CSS classes,Elements, Element IDs, Blocks</title><content type='html'>&lt;p&gt;&lt;a title="CSSItems" href="http://www.flickr.com/photos/9918938@N04/2110333609/"&gt;&lt;img border="0" alt="CSSItems" src="http://static.flickr.com/2221/2110333609_d93d3fb37b.jpg"&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;In visual studio, when you edit the CSS files, you can see the different sections which are supported by CSS. I have a couple of confusions regarding the difference between them.&lt;/p&gt; &lt;ol&gt; &lt;li&gt;What is the difference between &lt;em&gt;&lt;strong&gt;Element Id and Classes&lt;/strong&gt;&lt;/em&gt;. Here is a &lt;a href="http://css-discuss.incutio.com/?page=ClassesVsIds"&gt;good explanation&lt;/a&gt; about this . Format wise, A CLASS is preceded by a dot (.), and an ID with a hash mark (#), then the CLASS or ID name and the declaration. &lt;strong&gt;With the ID selector you identify an element to be an *unique instance* in a document. &lt;/strong&gt;You can declare a CLASS and apply this class to all elements inside the BODY, a &amp;lt;p&amp;gt;, a &amp;lt;span&amp;gt; and a &amp;lt;div&amp;gt; multiple times within the same document, on the same page, without any problems. &lt;strong&gt;IDs have more weight than classes. &lt;/strong&gt; &lt;li&gt;What is the difference between &lt;em&gt;&lt;strong&gt;Elements and Element IDs/Classes&lt;/strong&gt;. &lt;/em&gt;The Element is another level down from the Element IDs or Classes. For example, you have a Id name tablist here. &lt;pre class="csharpcode"&gt;    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;div&lt;/span&gt; &lt;span class="attr"&gt;id&lt;/span&gt;&lt;span class="kwrd"&gt;="tablist"&lt;/span&gt; &lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;br&gt;      &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;ul&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;li&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;a&lt;/span&gt; &lt;span class="attr"&gt;href&lt;/span&gt;&lt;span class="kwrd"&gt;="AgencyList.aspx"&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;Agency List&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;a&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;li&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;ul&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;br&gt;      &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;ul&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;li&lt;/span&gt; &lt;span class="attr"&gt;id&lt;/span&gt;&lt;span class="kwrd"&gt;="current"&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;a&lt;/span&gt; &lt;span class="attr"&gt;href&lt;/span&gt;&lt;span class="kwrd"&gt;="#"&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;Agency Details&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;a&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;li&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;ul&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;br&gt;  &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;div&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre class="csharpcode"&gt;&lt;/pre&gt;&lt;br&gt;&lt;br /&gt;&lt;p&gt;&lt;span class="kwrd"&gt;&lt;span style="font-family: trebuchet ms; color: rgb(0,0,0)"&gt;You define tablist as the Element Ids, but you can further define tablist ul, tablist li as the Elements, which are kind of one level below and essentially html elements.&lt;/span&gt;&amp;nbsp; Similarly, you can define class firstly, and then define Elements. Element&amp;nbsp; apply to the intrinsic&amp;nbsp; html element such as body, h1, h2, p.&lt;/span&gt;&lt;/p&gt;&lt;br /&gt;&lt;li&gt;&lt;br /&gt;&lt;p&gt;&lt;span class="kwrd"&gt;Element Id ends with “#” sign, Classes end with “.” sign, and Element ends with “nothing” :-)&lt;/span&gt;&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7462882-5641410586659187587?l=gisresearch.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gisresearch.blogspot.com/feeds/5641410586659187587/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7462882&amp;postID=5641410586659187587' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7462882/posts/default/5641410586659187587'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7462882/posts/default/5641410586659187587'/><link rel='alternate' type='text/html' href='http://gisresearch.blogspot.com/2007/12/css-classeselements-element-ids-blocks.html' title='CSS classes,Elements, Element IDs, Blocks'/><author><name>J.W.</name><uri>http://www.blogger.com/profile/09241601264454722977</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://farm3.static.flickr.com/2116/1856041089_20ef060d43_o.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7462882.post-5180071517005709356</id><published>2007-11-22T16:16:00.001-05:00</published><updated>2007-11-22T16:16:36.892-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Asp.Net'/><title type='text'>Ajax UpdatePanel , GridView , CommandField</title><content type='html'>&lt;p&gt;I encountered a strange problem when working with a GridView control inside an Asp.Net ajax update panel. Basically, I have a portion of code look like this&lt;/p&gt; &lt;div style="border-right: gray 1px solid; padding-right: 4px; border-top: gray 1px solid; padding-left: 4px; font-size: 8pt; padding-bottom: 4px; margin: 20px 0px 10px; overflow: auto; border-left: gray 1px solid; width: 97.5%; cursor: text; max-height: 200px; line-height: 12pt; padding-top: 4px; border-bottom: gray 1px solid; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4"&gt; &lt;div style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   1:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;asp:UpdatePanel&lt;/span&gt; &lt;span style="color: #ff0000"&gt;ID&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="UpdatePanel1"&lt;/span&gt; &lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   2:&lt;/span&gt;                      &lt;span style="color: #ff0000"&gt;UpdateMode&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="Conditional"&lt;/span&gt; &lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   3:&lt;/span&gt;                      &lt;span style="color: #ff0000"&gt;runat&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="server"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   4:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;ContentTemplate&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;   &lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   5:&lt;/span&gt;&amp;nbsp; &lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   6:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;asp:GridView&lt;/span&gt; &lt;span style="color: #ff0000"&gt;id&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="dgIFSPServices"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;runat&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="server"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;PageSize&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="15"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;AllowPaging&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="True"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;AllowSorting&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="True"&lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   7:&lt;/span&gt;                     &lt;span style="color: #ff0000"&gt;AutoGenerateColumns&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="False"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Font-Size&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="9pt"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Font-Names&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="Arial"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;width&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="100%"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;IsSortedAscending&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="True"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;BorderWidth&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="1px"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;BorderStyle&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="Solid"&lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   8:&lt;/span&gt;                     &lt;span style="color: #ff0000"&gt;ForeColor&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="Black"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;DataKeyNames&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="IFSPServiceID"&lt;/span&gt;   &lt;span style="color: #ff0000"&gt;DefaultSort&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="StartDate"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;RecordCount&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="0"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;OnRowEditing&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="dgIFSPServices_RowEditing"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   9:&lt;/span&gt;                     &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;Columns&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  10:&lt;/span&gt;                         &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;asp:CommandField&lt;/span&gt; &lt;span style="color: #ff0000"&gt;ButtonType&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="Image"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;EditImageUrl&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="../../../Images/Edit.gif"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;ShowCancelButton&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="False"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;ShowEditButton&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="True"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;asp:CommandField&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  11:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;asp:GridView&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  12:&lt;/span&gt;&amp;nbsp; &lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  13:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;ContentTemplate&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  14:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;asp:UpdatePanel&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;And in the code behind page, &lt;/p&gt;&lt;br /&gt;&lt;div style="border-right: gray 1px solid; padding-right: 4px; border-top: gray 1px solid; padding-left: 4px; font-size: 8pt; padding-bottom: 4px; margin: 20px 0px 10px; overflow: auto; border-left: gray 1px solid; width: 97.5%; cursor: text; max-height: 200px; line-height: 12pt; padding-top: 4px; border-bottom: gray 1px solid; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4"&gt;&lt;br /&gt;&lt;div style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   1:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;protected&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; Page_Load(&lt;span style="color: #0000ff"&gt;object&lt;/span&gt; sender, EventArgs e)&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   2:&lt;/span&gt; {&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   3:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (!IsPostBack)&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   4:&lt;/span&gt; {&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   5:&lt;/span&gt; &lt;span style="color: #008000"&gt;//Only binding data when the page is loaded at the first time.&lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   6:&lt;/span&gt; }&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   7:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;else&lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   8:&lt;/span&gt; {&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   9:&lt;/span&gt; }&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  10:&lt;/span&gt; }&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Every time, when I click the edit button in the &amp;lt;asp:CommandField&amp;gt; , the Page_Load is called twice. At the first time, IsPostBack is true, and the second time, IsPostBack is false. Since I have some special code which I definitely only want to run it when the page first loads, this double loading behavior causes some unpleasant effects.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;After some extensive search, I found the answer in &lt;a href="http://forums.asp.net/p/1109738/1706346.aspx"&gt;this post&lt;/a&gt;. It was decided how the command field is interpreted by the asp.net and rendered in the html page. In my example, it was rendered as &lt;/p&gt;&lt;br /&gt;&lt;div style="border-right: gray 1px solid; padding-right: 4px; border-top: gray 1px solid; padding-left: 4px; font-size: 8pt; padding-bottom: 4px; margin: 20px 0px 10px; overflow: auto; border-left: gray 1px solid; width: 97.5%; cursor: text; max-height: 200px; line-height: 12pt; padding-top: 4px; border-bottom: gray 1px solid; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4"&gt;&lt;br /&gt;&lt;div style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   1:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;INPUT&lt;/span&gt; &lt;span style="color: #ff0000"&gt;style&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="BORDER-TOP-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   2:&lt;/span&gt;  BORDER-RIGHT-WIDTH: 0px"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;onclick&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="javascript:__doPostBack('ctl00$ContentPlaceHolderBody$IFSPReviewOld$dgIFSPServices','Edit$0')"&lt;/span&gt; &lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   3:&lt;/span&gt; &lt;span style="color: #ff0000"&gt;type&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="image"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;alt&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="Edit"&lt;/span&gt; &lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   4:&lt;/span&gt; &lt;span style="color: #ff0000"&gt;src&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="http://localhost:29162/Odh.EarlyTrack.UI/Images/Edit.gif"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;value&lt;/span&gt;&lt;span style="color: #0000ff"&gt;=""&lt;/span&gt; &lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;p&gt;The input type="image" is treated as a submit button by the browser, and will load the page once with IsPostBack=false, and onclick will load the page once again with the IsPostBack=true.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;There is another alternative workaround in the post, you can subclass the linkbutton class, and use the linkbutton inside a template field to achieve the same purpose without the double post.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7462882-5180071517005709356?l=gisresearch.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gisresearch.blogspot.com/feeds/5180071517005709356/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7462882&amp;postID=5180071517005709356' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7462882/posts/default/5180071517005709356'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7462882/posts/default/5180071517005709356'/><link rel='alternate' type='text/html' href='http://gisresearch.blogspot.com/2007/11/ajax-updatepanel-gridview-commandfield.html' title='Ajax UpdatePanel , GridView , CommandField'/><author><name>J.W.</name><uri>http://www.blogger.com/profile/09241601264454722977</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://farm3.static.flickr.com/2116/1856041089_20ef060d43_o.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7462882.post-218258105776196158</id><published>2007-11-04T09:01:00.001-05:00</published><updated>2007-11-04T09:01:03.250-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Tools'/><title type='text'>svn-time-lapse-view</title><content type='html'>&lt;p&gt;I use VSTS for my paid work at office, but I use SVN for my side project at home. I found this tool &lt;a href="http://code.google.com/p/svn-time-lapse-view/"&gt;svn-time-lapse-view&lt;/a&gt; from some post, and was really impressed with the functionality it provides. This tool can download up to 100 revisions of the files, and by simply moving the revision progress bar on the top, you can easily check the modifications between different revisions. &lt;/p&gt; &lt;p&gt;This guy who developed this tool is really amazing,&amp;nbsp; I have downloaded another open-source project (JTS geometry library) they developed before, and that was amazing too.&lt;/p&gt; &lt;p&gt;Another tool in my toolset.&lt;/p&gt; &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7462882-218258105776196158?l=gisresearch.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gisresearch.blogspot.com/feeds/218258105776196158/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7462882&amp;postID=218258105776196158' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7462882/posts/default/218258105776196158'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7462882/posts/default/218258105776196158'/><link rel='alternate' type='text/html' href='http://gisresearch.blogspot.com/2007/11/svn-time-lapse-view.html' title='svn-time-lapse-view'/><author><name>J.W.</name><uri>http://www.blogger.com/profile/09241601264454722977</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://farm3.static.flickr.com/2116/1856041089_20ef060d43_o.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7462882.post-3520065886614593473</id><published>2007-11-01T08:19:00.001-04:00</published><updated>2007-11-01T08:26:10.743-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Tools'/><category scheme='http://www.blogger.com/atom/ns#' term='Asp.Net'/><title type='text'>Web Testing</title><content type='html'>&lt;p&gt;I have been helping our testers automate the test for our web applications, and right now, we are using VSTS testing and fiddler. Based on some information gathered from &lt;a href="http://dotavery.com/blog/archive/2007/10/24/149435.aspx"&gt;a post&lt;/a&gt; by James Avery, it seems I need check out some other options there, like &lt;a href="http://watin.sourceforge.net/index.html"&gt;WaitN&lt;/a&gt;,  &lt;a href="http://watintestrecord.sourceforge.net/"&gt;WaitN test recorder&lt;/a&gt;, also &lt;a href="http://www.openqa.org/selenium/"&gt;selenium&lt;/a&gt;, I guess my to do list will get much longer now.&lt;/p&gt; &lt;p&gt;And the biggest headache for our application is the lacking of automating testing, and since the application was developed by some other contractors originally, I am very cautions to change any code since there is no automatic verification. &lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7462882-3520065886614593473?l=gisresearch.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gisresearch.blogspot.com/feeds/3520065886614593473/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7462882&amp;postID=3520065886614593473' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7462882/posts/default/3520065886614593473'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7462882/posts/default/3520065886614593473'/><link rel='alternate' type='text/html' href='http://gisresearch.blogspot.com/2007/11/web-testing.html' title='Web Testing'/><author><name>J.W.</name><uri>http://www.blogger.com/profile/09241601264454722977</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://farm3.static.flickr.com/2116/1856041089_20ef060d43_o.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7462882.post-919693466757438096</id><published>2007-10-31T22:06:00.001-04:00</published><updated>2007-11-01T09:09:11.070-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Tools'/><category scheme='http://www.blogger.com/atom/ns#' term='.Net'/><title type='text'>AVIcode experience</title><content type='html'>&lt;p&gt;I have been working on a project called "EarlyTrack" for the state of Ohio in the last 8 months, and the best thing I found is the &lt;a href="http://www.avicode.com/default.htm"&gt;"AVICode" monitoring tool&lt;/a&gt; installed on the production machine.&lt;/p&gt; &lt;p&gt;As a developer for the last 6 years, I understand that every application will have bugs in production no matter how much you test on your test environment. But when the user complains that they have ran into an issue, it is very hard to find what exactly goes wrong because of the challenge of recreating the exactly same issue.  AVICode provides the exactly solutions for this kind of issue, it intercepts the exceptions thrown by the system and records very detailed information on what exactly happened in the cod when the bugs were triggered.&lt;/p&gt; &lt;p&gt;The most impressive thing is that if you installed the pdb(debugging database) file alongside the released binary file, every time a bug triggers, you can double click to get to the exact line of code which failed. &lt;/p&gt; &lt;p&gt;I'll take some screen shots later on..&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7462882-919693466757438096?l=gisresearch.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gisresearch.blogspot.com/feeds/919693466757438096/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7462882&amp;postID=919693466757438096' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7462882/posts/default/919693466757438096'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7462882/posts/default/919693466757438096'/><link rel='alternate' type='text/html' href='http://gisresearch.blogspot.com/2007/10/avicode-experience.html' title='AVIcode experience'/><author><name>J.W.</name><uri>http://www.blogger.com/profile/09241601264454722977</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://farm3.static.flickr.com/2116/1856041089_20ef060d43_o.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7462882.post-2990875581892364382</id><published>2007-10-31T21:31:00.001-04:00</published><updated>2008-08-16T18:06:32.341-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='C++'/><title type='text'>C String.</title><content type='html'>&lt;p&gt;There is a good article about &lt;a href="http://www.cs.bu.edu/teaching/cpp/string/array-vs-ptr"&gt;C String&lt;/a&gt;,&amp;#160; basically, there are two ways of declaring a string, either statically or dynamically. &lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;To declared&amp;#160; a string statically, we can either declare an explicit number of string length or not.&amp;#160; &lt;/li&gt; &lt;/ol&gt;  &lt;div style="border-right: gray 1px solid; padding-right: 4px; border-top: gray 1px solid; padding-left: 4px; font-size: 8pt; padding-bottom: 4px; margin: 20px 0px 10px; overflow: auto; border-left: gray 1px solid; width: 95.27%; cursor: text; max-height: 200px; line-height: 12pt; padding-top: 4px; border-bottom: gray 1px solid; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; height: 64px; background-color: #f4f4f4"&gt;   &lt;div style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;     &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   1:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;char&lt;/span&gt; label1[]=&lt;span style="color: #006080"&gt;&amp;quot;I am a test!&amp;quot;&lt;/span&gt;;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   2:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;char&lt;/span&gt; label2[100]=&lt;span style="color: #006080"&gt;&amp;quot;I am a test!&amp;quot;&lt;/span&gt;;&lt;/pre&gt;&lt;br /&gt;  &lt;/div&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;The length of the first string is decided by the actual string length, while the second string is explicitly declared as having the length of 100. Both of ways declare a mutable string,&amp;#160; which is different with &lt;font color="#ff0000"&gt;char* label3=&amp;quot;I am a test!&amp;quot;.&amp;#160; &lt;/font&gt;&lt;font color="#000000"&gt;The later one are essentially the same with &lt;font color="#ff0000"&gt;const char* label3=&amp;quot;I am a test!&amp;quot;&lt;/font&gt; . If you try to do something like lable3[0]='i', you will encounter an access violation error.&lt;/font&gt;&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;Here is a &lt;a href="http://www.codeguru.com/forum/showthread.php?t=351721"&gt;good link&lt;/a&gt; about this problem: Basically, when you declare &lt;font color="#ff0000"&gt;char* label3=&amp;quot;I am a test!&amp;quot;. &lt;/font&gt;&amp;#160; it will be a constant string in the data section, this string constant has always the same address and is constant. You should always consider &lt;font color="#ff0000"&gt;const char* label3=&amp;quot;I am a test!&amp;quot;&lt;/font&gt;&amp;#160; because the former is only for backward purpose.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&amp;#160;&amp;#160; 2.&amp;#160; To declare a string dynamically, the string length has to be passed in like this char* dynamicalString=new string[length+1]. The last character is reserved for '\0', the end of string. The string length (strlen) is length, not length+1.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7462882-2990875581892364382?l=gisresearch.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gisresearch.blogspot.com/feeds/2990875581892364382/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7462882&amp;postID=2990875581892364382' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7462882/posts/default/2990875581892364382'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7462882/posts/default/2990875581892364382'/><link rel='alternate' type='text/html' href='http://gisresearch.blogspot.com/2007/10/c-string.html' title='C String.'/><author><name>J.W.</name><uri>http://www.blogger.com/profile/09241601264454722977</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://farm3.static.flickr.com/2116/1856041089_20ef060d43_o.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7462882.post-1482222227433801717</id><published>2007-10-11T21:52:00.001-04:00</published><updated>2007-10-11T21:52:44.474-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='.Net'/><category scheme='http://www.blogger.com/atom/ns#' term='Enterprise Library'/><title type='text'>Enterprise Library configuration.</title><content type='html'>&lt;p&gt;&lt;a href="http://www.pnpguidance.net/Post/ManagingEnterpriseLibraryConfigurationSetsCustomEnterpriseLibraryMicrosoftSigned.aspx"&gt;A very good post&lt;/a&gt; on how to change the configuration of the enterprise library.&lt;/p&gt; &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7462882-1482222227433801717?l=gisresearch.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gisresearch.blogspot.com/feeds/1482222227433801717/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7462882&amp;postID=1482222227433801717' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7462882/posts/default/1482222227433801717'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7462882/posts/default/1482222227433801717'/><link rel='alternate' type='text/html' href='http://gisresearch.blogspot.com/2007/10/enterprise-library-configuration.html' title='Enterprise Library configuration.'/><author><name>J.W.</name><uri>http://www.blogger.com/profile/09241601264454722977</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://farm3.static.flickr.com/2116/1856041089_20ef060d43_o.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7462882.post-5066756941133852581</id><published>2007-09-26T16:52:00.001-04:00</published><updated>2007-09-26T16:52:55.452-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='.Net'/><title type='text'>Assembly Load, LoadFrom, LoadFile</title><content type='html'>&lt;p&gt;I think I am not very clear about those different loading functions, so I  looked up a couple of different sources, and it helps a lot. Here are some  understanding I summarized:&lt;/p&gt; &lt;ol&gt;&lt;li&gt;If possible, it's better to call Load instead of LoadFrom since the later  has to call the first anyway.&lt;/li&gt;&lt;li&gt;LoadFrom actually calls the Load method: Internally, LoadFrom will firstly  try to get the AssemblyName by call  System.Reflection.AssemblyName.GetAssemblyName( path) method, then it will call  Assembly's Load method, passing it the AssemblyName object. If load fails to  find an assembly, then LoadFrom loads the assembly at the path name specified in  the LoadFrom method. It is possible that there exist two different assemblies  which have the same identity, so when LoadFrom internally calls Load, it may  load an assembly which is different with the path you specified in the  LoadFrom.&lt;/li&gt;&lt;li&gt;LoadFile will load the assembly without CLR applying any policies or  searching.&lt;/li&gt;&lt;li&gt;When Load looks for the assembly, it will be based on the following  searching path:&lt;/li&gt;&lt;ol&gt;&lt;li&gt;GAC&lt;/li&gt;&lt;li&gt;Application's base directory.&lt;/li&gt;&lt;li&gt;Private path subdirectories.&lt;/li&gt;&lt;li&gt;code base locations.&lt;/li&gt;&lt;/ol&gt;&lt;li&gt;Load has two versions, one is Load(AssembyName), the other is Load(String).  When you use the the second method to load, your normally pass in a string like  this "mscorlib, Version=2.0.0.0, Culture=neutral,  PublicKeyToken=b77a5c561934e089". Remember, the first section of the string is  name, which doesn't include the path and extension. If you choose to use  AssemblyName to load, there are three situations.&lt;/li&gt;&lt;ol&gt;&lt;li&gt;You didn't specify the codebase, but include other bits. If you don't  specify the code base, and set the AssemblyName.Name, CultureInfo, public key  token / public key and/or Version properties, it's essentially the same as the  Load(String), because you just parse out that string and put it in individual  fields. &lt;/li&gt;&lt;li&gt;You specify the codebase, not the name. The code base will have the format  look like "&lt;a title="file:///C:/WINDOWS/Microsoft.NET/Framework/v2.0.50727/mscorlib.dll" href="file:///C:/Documents%20and%20Settings/Jianwei.Sun/Application%20Data/Windows%20Live%20Writer/PostSupportingFiles/ae873013-c8af-4d37-877f-088183342940/mscorlib.dll"&gt;file:///C:/WINDOWS/Microsoft.NET/Framework/v2.0.50727/mscorlib.dll&lt;/a&gt;",  and if you set the codebase, not the name, then, it's doing the same thing as  Assembly.LoadFrom() method based on that code base.&lt;/li&gt;&lt;li&gt;When both are specified, then we do step 1 firstly, and if step 1 failed, we  do step 2. The thing which worth noting is when you call  Assembly.Load(AssemblyName) with a codepath, it does not mean the assembly will  be loaded from that path.&lt;/li&gt;&lt;/ol&gt;&lt;/ol&gt; &lt;p&gt;References:&lt;/p&gt; &lt;p&gt;&lt;a href="http://blogs.msdn.com/suzcook/default.aspx"&gt;Suzanne Cook's .NET CLR  Notes&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;a href="http://www.amazon.com/CLR-via-Second-Pro-Developer/dp/0735621632"&gt;CLR via  C#&lt;/a&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7462882-5066756941133852581?l=gisresearch.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gisresearch.blogspot.com/feeds/5066756941133852581/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7462882&amp;postID=5066756941133852581' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7462882/posts/default/5066756941133852581'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7462882/posts/default/5066756941133852581'/><link rel='alternate' type='text/html' href='http://gisresearch.blogspot.com/2007/09/assembly-load-loadfrom-loadfile.html' title='Assembly Load, LoadFrom, LoadFile'/><author><name>J.W.</name><uri>http://www.blogger.com/profile/09241601264454722977</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://farm3.static.flickr.com/2116/1856041089_20ef060d43_o.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7462882.post-8497450578843905187</id><published>2007-09-17T22:11:00.001-04:00</published><updated>2007-11-06T10:48:36.829-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='SQL'/><title type='text'>SQL Server performance tuning.</title><content type='html'>&lt;p&gt;My experience tells me that if your web  applications (or even the windows applications) run slower, 90 percent of the time, it's because some sql queries, stored procedures, indexes on the tables are not optimized.  It's very important that you can find which query, which table are running slowly.&lt;/p&gt; &lt;p&gt;The book "&lt;b&gt;SQL Server Query Performance Tuning Distilled&lt;/b&gt;" by  Sajal Dam is a very good book on this topic. &lt;/p&gt; &lt;ol&gt; &lt;li&gt;Use the sql profiler to find what queries are taking long time, but I finds out it's not very pleasant to work with the user interface of the profiler. It's especially annoying even if you click on the stop button, the events are still being logged. (The stop command sent through the user interface is taking long time because the logging thread is very busy in logging the events in the sql server. This is a typical scenario when you try to kill a thread which is in a busy while loop.) The author provides an alternative way to do this, you can use the sql profiler to create a template or open an existing template, and stop the log immediately after starting the log (You only need do this once, so it won't be too painful). You don't have to do that, this step simply helps you to prepare the sql scripts. You can use sp_trace_create, sp_trace_setevent, sp_trace_setfilter to create all the scripts manually. In the profiler, you can script the trace definition and the step to run the trace to a SQL script file by selecting File-&amp;gt;Script Trace -&amp;gt; For SQL Server 2000. &lt;a title="SQLProfilerScript" href="http://www.flickr.com/photos/9918938@N04/1454066265/"&gt;&lt;img alt="SQLProfilerScript" src="http://static.flickr.com/1359/1454066265_e2bb8667cb.jpg" border="0" /&gt;&lt;/a&gt; &lt;/li&gt;&lt;li&gt;Open the saved script file in Query Analyzer, and modify the InsertFileNameHere parameter of sp_trace_create to a meaningful filename. &lt;a title="ChangeScriptFileName" href="http://www.flickr.com/photos/9918938@N04/1454956592/"&gt;&lt;img alt="ChangeScriptFileName" src="http://static.flickr.com/1125/1454956592_78c69afad1.jpg" border="0" /&gt;&lt;/a&gt; &lt;/li&gt;&lt;li&gt;Execute the sql script, which will start the SQL trace as a background process. It also returns the &lt;span style="color:#ff0000;"&gt;ID of the trace as traceid&lt;/span&gt;, which is very important and required to stop the trace later on.  You can use the &lt;span style="color:#ff0000;"&gt;SELECT * FROM &lt;a href="http://msdn2.microsoft.com/en-us/library/ms173875.aspx"&gt;::fn_trace_getinfo(default)&lt;/a&gt; &lt;/span&gt;&lt;span style="color:#000000;"&gt; to find the trace status.&lt;/span&gt;  &lt;/li&gt;&lt;li&gt;Use EXEC sp_trace_setstatus traceid, 0 to stop the trace and EXEC sp_trace_setstatus 1,2 to close the trace.  &lt;/li&gt;&lt;li&gt;Open the trace log file in the profiler and save it to a table, and you can query the cpu time, logical read, or anything else you selected in the profiling process.&lt;/li&gt;&lt;/ol&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7462882-8497450578843905187?l=gisresearch.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gisresearch.blogspot.com/feeds/8497450578843905187/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7462882&amp;postID=8497450578843905187' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7462882/posts/default/8497450578843905187'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7462882/posts/default/8497450578843905187'/><link rel='alternate' type='text/html' href='http://gisresearch.blogspot.com/2007/09/sql-server-performance-tuning.html' title='SQL Server performance tuning.'/><author><name>J.W.</name><uri>http://www.blogger.com/profile/09241601264454722977</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://farm3.static.flickr.com/2116/1856041089_20ef060d43_o.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7462882.post-7905970170584144399</id><published>2007-08-25T08:30:00.001-04:00</published><updated>2007-08-25T08:30:55.704-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='.Net'/><title type='text'>Pass by value or Pass by reference</title><content type='html'>&lt;p&gt;Here is a simple example of parameter passing in C#..&lt;/p&gt; &lt;div style="border-right: gray 1px solid; padding-right: 4px; border-top: gray 1px solid; padding-left: 4px; font-size: 8pt; padding-bottom: 4px; margin: 20px 0px 10px; overflow: auto; border-left: gray 1px solid; width: 97.5%; cursor: text; max-height: 200px; line-height: 12pt; padding-top: 4px; border-bottom: gray 1px solid; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4"&gt; &lt;div style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   1:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; ParameterPassingSample&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   2:&lt;/span&gt; {&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   3:&lt;/span&gt;     &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; ParameterPassingSample()&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   4:&lt;/span&gt;     {&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   5:&lt;/span&gt;     }&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   6:&lt;/span&gt; &amp;nbsp;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   7:&lt;/span&gt;     &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt;  CallingMethod()&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   8:&lt;/span&gt;     {&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   9:&lt;/span&gt;         StringBuilder sb1 = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; StringBuilder(&lt;span style="color: #006080"&gt;"Test"&lt;/span&gt;);&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  10:&lt;/span&gt;         CalledMethod(sb1);&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  11:&lt;/span&gt;         System.Diagnostics.Debug.Assert(&lt;span style="color: #006080"&gt;"Test test"&lt;/span&gt;==sb1.ToString(),&lt;span style="color: #006080"&gt;"String equal"&lt;/span&gt;);&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  12:&lt;/span&gt;     }&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  13:&lt;/span&gt; &amp;nbsp;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  14:&lt;/span&gt;     &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; CalledMethod(StringBuilder sb2)&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  15:&lt;/span&gt;     {&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  16:&lt;/span&gt;         sb2.Append(&lt;span style="color: #006080"&gt;" test"&lt;/span&gt;);&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  17:&lt;/span&gt;     }&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  18:&lt;/span&gt; }&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;p&gt;Since CalledMethod&amp;nbsp; function changed the sb value, it will easily give you an impression that Parameter is passed by reference. Actually, it's not.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;a title="parameter memory layour" href="http://www.flickr.com/photos/9918938@N04/1231349058/"&gt;&lt;img alt="parameter memory layour" src="http://static.flickr.com/1142/1231349058_85a10f498d.jpg" border="0"&gt;&lt;/a&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Sb2 is&amp;nbsp;a new string builder object, and it points to the same string builder object in memory. So, when CalledMethod change the value, the value which the original string object (sb1) refers also change. This doesn't mean "pass by reference", it is still "pass by value".&amp;nbsp; Here is another example to show this.&lt;/p&gt;&lt;br /&gt;&lt;div style="border-right: gray 1px solid; padding-right: 4px; border-top: gray 1px solid; padding-left: 4px; font-size: 8pt; padding-bottom: 4px; margin: 20px 0px 10px; overflow: auto; border-left: gray 1px solid; width: 97.5%; cursor: text; max-height: 200px; line-height: 12pt; padding-top: 4px; border-bottom: gray 1px solid; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4"&gt;&lt;br /&gt;&lt;div style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   1:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; ParameterPassingSample&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   2:&lt;/span&gt; {&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   3:&lt;/span&gt;     &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; ParameterPassingSample()&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   4:&lt;/span&gt;     {&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   5:&lt;/span&gt;     }&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   6:&lt;/span&gt; &amp;nbsp;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   7:&lt;/span&gt;     &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt;  CallingMethod()&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   8:&lt;/span&gt;     {&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   9:&lt;/span&gt;         StringBuilder sb1 = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; StringBuilder(&lt;span style="color: #006080"&gt;"Test"&lt;/span&gt;);&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  10:&lt;/span&gt;         CalledMethod(sb1);&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  11:&lt;/span&gt;         System.Diagnostics.Debug.Assert(&lt;span style="color: #006080"&gt;"Test"&lt;/span&gt;==sb1.ToString(),&lt;span style="color: #006080"&gt;"String equal"&lt;/span&gt;);&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  12:&lt;/span&gt;     }&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  13:&lt;/span&gt; &amp;nbsp;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  14:&lt;/span&gt;     &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; CalledMethod(StringBuilder sb2)&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  15:&lt;/span&gt;     {&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  16:&lt;/span&gt;         sb2 = &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  17:&lt;/span&gt;     }&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  18:&lt;/span&gt; }&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;p&gt;Here , if sb2 changes to null, it doesn't affect the value of sb1.&amp;nbsp;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;a title="parameter memory layour" href="http://www.flickr.com/photos/9918938@N04/1230520347/"&gt;&lt;img alt="parameter memory layour" src="http://static.flickr.com/1357/1230520347_fb7f580444.jpg" border="0"&gt;&lt;/a&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;The difference between those two examples are "change the value the parameter points to" or "change the value of the parameter itself".&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7462882-7905970170584144399?l=gisresearch.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gisresearch.blogspot.com/feeds/7905970170584144399/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7462882&amp;postID=7905970170584144399' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7462882/posts/default/7905970170584144399'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7462882/posts/default/7905970170584144399'/><link rel='alternate' type='text/html' href='http://gisresearch.blogspot.com/2007/08/pass-by-value-or-pass-by-reference.html' title='Pass by value or Pass by reference'/><author><name>J.W.</name><uri>http://www.blogger.com/profile/09241601264454722977</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://farm3.static.flickr.com/2116/1856041089_20ef060d43_o.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7462882.post-1855434885629427069</id><published>2007-08-20T22:23:00.001-04:00</published><updated>2007-08-20T22:23:40.209-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='.Net'/><title type='text'>What are the overhead fields when you create an object in CLR</title><content type='html'>&lt;p&gt;In CLR, each object has two overhead fields: a type object pointer and a sync block index.&lt;a title="ObjectsLayOutCLR" href="http://www.flickr.com/photos/9918938@N04/1188255157/"&gt;&lt;img alt="ObjectsLayOutCLR" src="http://static.flickr.com/1270/1188255157_a540e6e687.jpg" border="0"&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Each of the fields requires 32 bits, adding 8 bytes to each object.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7462882-1855434885629427069?l=gisresearch.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gisresearch.blogspot.com/feeds/1855434885629427069/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7462882&amp;postID=1855434885629427069' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7462882/posts/default/1855434885629427069'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7462882/posts/default/1855434885629427069'/><link rel='alternate' type='text/html' href='http://gisresearch.blogspot.com/2007/08/what-are-overhead-fields-when-you.html' title='What are the overhead fields when you create an object in CLR'/><author><name>J.W.</name><uri>http://www.blogger.com/profile/09241601264454722977</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://farm3.static.flickr.com/2116/1856041089_20ef060d43_o.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7462882.post-3797470229871633028</id><published>2007-08-20T14:26:00.001-04:00</published><updated>2007-08-20T14:26:39.016-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='.Net'/><title type='text'>WaitHandle hierarchy</title><content type='html'>&lt;p&gt;Here is a reflector screenshot&amp;nbsp;of the relationships&amp;nbsp;among the different synchronization object. The wait handle is a simple class whose sole purpose is to wrap a windows kernel object.&lt;/p&gt; &lt;p&gt;&lt;a title="WaitHandleDelegate" href="http://www.flickr.com/photos/9918938@N04/1184350351/"&gt;&lt;img alt="WaitHandleDelegate" src="http://static.flickr.com/1168/1184350351_47a573a6e3.jpg" border="0"&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;As you can see, EventWaitHandle, Mutex, and Semaphore are all inheriting from the wait handle object. When a thread is waiting on the kernel object, the thread must always transition from the user mode to the kernel mode, causing the thread to incur a performance hit. So if you want to do the thread synchronization inside an AppDomain, it's best that you simply use the Monitor, which is much more efficient than the kernel object. However, if you have to do the synchronization between different appdomains, processes, you have to use those windows kernel objects.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7462882-3797470229871633028?l=gisresearch.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gisresearch.blogspot.com/feeds/3797470229871633028/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7462882&amp;postID=3797470229871633028' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7462882/posts/default/3797470229871633028'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7462882/posts/default/3797470229871633028'/><link rel='alternate' type='text/html' href='http://gisresearch.blogspot.com/2007/08/waithandle-hierarchy.html' title='WaitHandle hierarchy'/><author><name>J.W.</name><uri>http://www.blogger.com/profile/09241601264454722977</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://farm3.static.flickr.com/2116/1856041089_20ef060d43_o.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7462882.post-8283770600154558216</id><published>2007-08-18T00:11:00.001-04:00</published><updated>2007-08-18T00:11:46.355-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='.Net'/><title type='text'>Thread from the thread pool or dedicated thread.</title><content type='html'>&lt;p&gt;Use thread from the thread pool to execute some asynchronous task instead of a dedicated thread&amp;nbsp;can save the resources needed to create that dedicated&amp;nbsp;thread. &lt;/p&gt; &lt;p&gt;A dedicated thread is only needed if the thread needs to run in a special priority, since all the threads from the thread pool are running in the normal priority, and you don't have access to change the priority for the thread in the thread pool.&lt;/p&gt; &lt;p&gt;Another reason is that if the thread needs to be run in foreground, a dedicated thread is also needed&amp;nbsp;since all the threads in the thread pool are running in the background.&lt;/p&gt; &lt;p&gt;If the task is taking extremely long time to finish, then a dedicated thread is also needed because it is a little bit challenging for the thread pool to figure out whether to create additional thread when that task is running.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7462882-8283770600154558216?l=gisresearch.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gisresearch.blogspot.com/feeds/8283770600154558216/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7462882&amp;postID=8283770600154558216' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7462882/posts/default/8283770600154558216'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7462882/posts/default/8283770600154558216'/><link rel='alternate' type='text/html' href='http://gisresearch.blogspot.com/2007/08/thread-from-thread-pool-or-dedicated.html' title='Thread from the thread pool or dedicated thread.'/><author><name>J.W.</name><uri>http://www.blogger.com/profile/09241601264454722977</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://farm3.static.flickr.com/2116/1856041089_20ef060d43_o.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7462882.post-2106479383710803920</id><published>2007-08-17T14:54:00.001-04:00</published><updated>2007-08-25T07:45:48.511-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='.Net'/><title type='text'>Why do you want to explicit declare an event.</title><content type='html'>&lt;p&gt;In C#, you can simply declare an event by using this line :&lt;/p&gt; &lt;p&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;event&lt;/span&gt; EventHandler&amp;lt;EventArgs&amp;gt; MyImplicitEvent;&lt;br&gt;It's simple. But under the hood, the compiler did a lot of things for you. The line above will be translated into the &lt;/p&gt; &lt;div class="csharpcode"&gt; &lt;div style="border-right: gray 1px solid; padding-right: 4px; border-top: gray 1px solid; padding-left: 4px; font-size: 8pt; padding-bottom: 4px; margin: 20px 0px 10px; overflow: auto; border-left: gray 1px solid; width: 97.5%; cursor: text; max-height: 200px; line-height: 12pt; padding-top: 4px; border-bottom: gray 1px solid; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4"&gt; &lt;div style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   1:&lt;/span&gt; &lt;span style="color: #008000"&gt;// 1. A PRIVATE delegate field that is initialized to nullprivate &lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   2:&lt;/span&gt; EventHandler&amp;lt;EventArgs&amp;gt; MyImplicitEvent = &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   3:&lt;/span&gt; &lt;span style="color: #008000"&gt;// 2. A PUBLIC add_Xxx method (where xxx is the Event name)&lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   4:&lt;/span&gt; &lt;span style="color: #008000"&gt;// Allows objects to register interest in the event.&lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   5:&lt;/span&gt; [MethodImpl(MethodImplOptions.Synchronized)]&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   6:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; add_MyImplicitEvent(EventHandler&amp;lt;EventArgs&amp;gt; &lt;span style="color: #0000ff"&gt;value&lt;/span&gt;) &lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   7:&lt;/span&gt; {&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   8:&lt;/span&gt;     MyImplicitEvent = (EventHandler&amp;lt;EventArgs&amp;gt;)&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   9:&lt;/span&gt;     Delegate.Combine(MyImplicitEvent, &lt;span style="color: #0000ff"&gt;value&lt;/span&gt;);&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  10:&lt;/span&gt; }&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  11:&lt;/span&gt; &lt;span style="color: #008000"&gt;// 3. A PUBLIC remove_Xxx method (where Xxx is the Event name)&lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  12:&lt;/span&gt; &lt;span style="color: #008000"&gt;// Allows objects to unregister interest in the event.&lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  13:&lt;/span&gt; [MethodImpl(MethodImplOptions.Synchronized)]&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  14:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; remove_MyImplicitEvent(EventHandler&amp;lt;EventArgs&amp;gt; &lt;span style="color: #0000ff"&gt;value&lt;/span&gt;) &lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  15:&lt;/span&gt; {&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  16:&lt;/span&gt;     MyImplicitEvent = (EventHandler&amp;lt;EventArgs&amp;gt;)Delegate.Remove(MyImplicitEvent, &lt;span style="color: #0000ff"&gt;value&lt;/span&gt;);&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  17:&lt;/span&gt; }&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;br&gt;&lt;br /&gt;&lt;p&gt;&lt;span style="font-family: trebuchet ms"&gt;So, the compiler will inject the MethodImplOptions.Synchronized attribute into the add_ and remove_ method. By default, those methods implement the synchronization using the object itself as the the thread-synchronization lock. However, this object is &lt;span style="font-size: 130%"&gt;public, &lt;/span&gt;&lt;span style="font-size: 85%"&gt;and you shouldn't use this object to do the synchronization. Because the malicious code could use this public object to deadlock threads that use this instance of object.&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;span style="font-family: trebuchet ms"&gt;A better way to handle this to do the parts which compiler generated for you by yourself. like this.&lt;/span&gt;&lt;/p&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class="csharpcode"&gt;&lt;br /&gt;&lt;p&gt;&lt;/p&gt;&lt;br /&gt;&lt;div style="border-right: gray 1px solid; padding-right: 4px; border-top: gray 1px solid; padding-left: 4px; font-size: 8pt; padding-bottom: 4px; margin: 20px 0px 10px; overflow: auto; border-left: gray 1px solid; width: 97.5%; cursor: text; max-height: 200px; line-height: 12pt; padding-top: 4px; border-bottom: gray 1px solid; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4"&gt;&lt;br /&gt;&lt;div style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   1:&lt;/span&gt; &lt;span style="color: #008000"&gt;// Private instance field created to serve as thread synchronization lock       &lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   2:&lt;/span&gt;  &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;readonly&lt;/span&gt; &lt;span style="color: #0000ff"&gt;object&lt;/span&gt; m_eventLock = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; Object();        &lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   3:&lt;/span&gt;  &lt;span style="color: #008000"&gt;// Add private field that refers to the head of the delegate list       &lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   4:&lt;/span&gt;  &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; EventHandler&amp;lt;EventArgs&amp;gt; _myImplicitEvent;       &lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   5:&lt;/span&gt;  &lt;span style="color: #008000"&gt;// Add an event member to the class        &lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   6:&lt;/span&gt;  &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;event&lt;/span&gt; EventHandler&amp;lt;EventArgs&amp;gt; ImplicitEvent        &lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   7:&lt;/span&gt;  {            &lt;span style="color: #008000"&gt;// Explicitly implement the 'add' method            &lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   8:&lt;/span&gt;      add            &lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   9:&lt;/span&gt;      {                &lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  10:&lt;/span&gt;          &lt;span style="color: #008000"&gt;// Take the private lock and add a handler                &lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  11:&lt;/span&gt;          &lt;span style="color: #008000"&gt;// (passed as 'value') to the delegate list                &lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  12:&lt;/span&gt;          &lt;span style="color: #0000ff"&gt;lock&lt;/span&gt; (m_eventLock) { _myImplicitEvent += &lt;span style="color: #0000ff"&gt;value&lt;/span&gt;; }            &lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  13:&lt;/span&gt;      }            &lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  14:&lt;/span&gt;      &lt;span style="color: #008000"&gt;// Explicitly implement the 'remove' method            &lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  15:&lt;/span&gt;      remove           &lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  16:&lt;/span&gt;      {                &lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  17:&lt;/span&gt;          &lt;span style="color: #008000"&gt;// Take the private lock and remove a handler                &lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  18:&lt;/span&gt;          &lt;span style="color: #008000"&gt;// (passed as 'value') from the delegate list               &lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  19:&lt;/span&gt;          &lt;span style="color: #0000ff"&gt;lock&lt;/span&gt; (m_eventLock) { _myImplicitEvent -= &lt;span style="color: #0000ff"&gt;value&lt;/span&gt;; }            &lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  20:&lt;/span&gt;      }        &lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  21:&lt;/span&gt;  }&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;p&gt;&lt;span style="font-size: 180%; font-family: trebuchet ms"&gt;&lt;font size="2"&gt;This way, you use the private object m_event Lock to do the &lt;/font&gt;&lt;font size="2"&gt;synchronization, and you can avoid the problem (code outside of the class will have access to the synchronization object)&amp;nbsp;compiler generated &lt;/font&gt;&lt;font size="2"&gt;codes have.&lt;/font&gt;&lt;/span&gt;&lt;br&gt;&lt;br /&gt;&lt;style type="text/css"&gt;.csharpcode, .csharpcode pre&lt;br /&gt;{&lt;br /&gt; font-size: small;&lt;br /&gt; color: black;&lt;br /&gt; font-family: consolas, "Courier New", courier, monospace;&lt;br /&gt; background-color: #ffffff;&lt;br /&gt; /*white-space: pre;*/&lt;br /&gt;}&lt;br /&gt;.csharpcode pre { margin: 0em; }&lt;br /&gt;.csharpcode .rem { color: #008000; }&lt;br /&gt;.csharpcode .kwrd { color: #0000ff; }&lt;br /&gt;.csharpcode .str { color: #006080; }&lt;br /&gt;.csharpcode .op { color: #0000c0; }&lt;br /&gt;.csharpcode .preproc { color: #cc6633; }&lt;br /&gt;.csharpcode .asp { background-color: #ffff00; }&lt;br /&gt;.csharpcode .html { color: #800000; }&lt;br /&gt;.csharpcode .attr { color: #ff0000; }&lt;br /&gt;.csharpcode .alt &lt;br /&gt;{&lt;br /&gt; background-color: #f4f4f4;&lt;br /&gt; width: 100%;&lt;br /&gt; margin: 0em;&lt;br /&gt;}&lt;br /&gt;.csharpcode .lnum { color: #606060; }&lt;br /&gt;&lt;/style&gt;&lt;br /&gt;&lt;/p&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7462882-2106479383710803920?l=gisresearch.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gisresearch.blogspot.com/feeds/2106479383710803920/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7462882&amp;postID=2106479383710803920' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7462882/posts/default/2106479383710803920'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7462882/posts/default/2106479383710803920'/><link rel='alternate' type='text/html' href='http://gisresearch.blogspot.com/2007/08/why-do-you-want-to-explicit-declare.html' title='Why do you want to explicit declare an event.'/><author><name>J.W.</name><uri>http://www.blogger.com/profile/09241601264454722977</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://farm3.static.flickr.com/2116/1856041089_20ef060d43_o.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7462882.post-7983526989252267928</id><published>2007-08-12T22:56:00.001-04:00</published><updated>2007-08-12T22:57:18.463-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Tools'/><title type='text'>Paint.Net</title><content type='html'>&lt;p&gt;I used the Paint.Net to edit a couple of images today when I tried to edit the html template for my blog. I want to widen the content area,&amp;nbsp;and have to edit a couple of gif files.&lt;/p&gt; &lt;p&gt;I&amp;nbsp;have downloaded the paint.net before, but really didn't try it too much. It took me some time to get used to all those concepts if you haven't used any image editing software, but I have to admit it's a really powerful image editing tools if you cannot afford the expensive adobe Photoshop.&lt;/p&gt; &lt;p&gt;&lt;a href="http://www.getpaint.net/"&gt;Check it here.&lt;/a&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7462882-7983526989252267928?l=gisresearch.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gisresearch.blogspot.com/feeds/7983526989252267928/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7462882&amp;postID=7983526989252267928' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7462882/posts/default/7983526989252267928'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7462882/posts/default/7983526989252267928'/><link rel='alternate' type='text/html' href='http://gisresearch.blogspot.com/2007/08/paintnet.html' title='Paint.Net'/><author><name>J.W.</name><uri>http://www.blogger.com/profile/09241601264454722977</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://farm3.static.flickr.com/2116/1856041089_20ef060d43_o.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7462882.post-7351304239298570572</id><published>2007-08-12T22:36:00.001-04:00</published><updated>2007-08-12T22:36:29.977-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Tools'/><title type='text'>Changed the default blog template.</title><content type='html'>&lt;p&gt;One thing I don't like the blogger is the limited selection of template. I am happy with the one I selected right now, but it gave too much margin to the sidebar, and leave main content&amp;nbsp;area very thin. While it's fine at most times, I did run into a couple of awkward situations when I have to insert some images into the blogger. I have to resize the image to fit into the content area. &lt;/p&gt; &lt;p&gt;I start to play with the html templates codes, and a couple of places I have to edit are :&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;#outer-wrapper {&lt;br&gt;&lt;font color="#ff0000"&gt;&amp;nbsp; width: 947px; (change from 847 px to 947 px)&lt;/font&gt;&lt;br&gt;&amp;nbsp; margin: 0px auto 0;&lt;br&gt;&amp;nbsp; text-align: left;&lt;br&gt;&amp;nbsp; font: $bodyfont;&lt;br&gt;&lt;font color="#ff0000"&gt;&amp;nbsp; background: url(&lt;/font&gt;&lt;a href="http://jianweisun.com/tile.gif)"&gt;&lt;font color="#ff0000"&gt;http://jianweisun.com/tile.gif)&lt;/font&gt;&lt;/a&gt;&lt;font color="#ff0000"&gt; repeat-y; I also have to edit the&amp;nbsp;original tile.gif to make it wider.&lt;/font&gt;&lt;br&gt;&amp;nbsp; }  &lt;p&gt;#content-wrapper {&lt;br&gt;&amp;nbsp; margin-left: 42px; /* to avoid the border image */&lt;br&gt;&amp;nbsp; &lt;font color="#ff0000"&gt;width: 863px; (change from 763px to 863px)&lt;/font&gt;&lt;br&gt;&amp;nbsp; }  &lt;p&gt;#main {&lt;br&gt;&amp;nbsp; float: left;&lt;br&gt;&amp;nbsp; &lt;font color="#ff0000"&gt;width: 560px; (change from 460px to 560px)&lt;br&gt;&lt;/font&gt;&amp;nbsp; margin: 20px 0 0 0;&lt;br&gt;&amp;nbsp; padding: 0 0 0 1em;&lt;br&gt;&amp;nbsp; line-height: 1.5em;&lt;br&gt;&amp;nbsp; word-wrap: break-word; /* fix for long text breaking sidebar float in IE */&lt;br&gt;&amp;nbsp; overflow: hidden;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; /* fix for long non-text content breaking IE sidebar float */&lt;br&gt;&amp;nbsp; }  &lt;p&gt;&amp;nbsp;  &lt;p&gt;#header-wrapper {&lt;br&gt;&lt;font color="#ff0000"&gt;&amp;nbsp;&amp;nbsp; width: 947px; (Add this line)&lt;/font&gt;&lt;br&gt;&amp;nbsp; margin: 0;&lt;br&gt;&amp;nbsp; padding: 0;&lt;br&gt;&amp;nbsp; font: $pagetitlefont;&lt;br&gt;&amp;nbsp; background: #e0e0e0 url&lt;font color="#ff0000"&gt;(&lt;/font&gt;&lt;a href="http://jianweisun.com/top_div_blue_947.gif"&gt;&lt;font color="#ff0000"&gt;http://jianweisun.com/top_div_blue_947.gif&lt;/font&gt;&lt;/a&gt;&lt;font color="#ff0000"&gt;) This image is also needed to be widened.&lt;br&gt;&lt;/font&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; no-repeat 0px 0px;&lt;br&gt;&amp;nbsp; }  &lt;p&gt;#header {&lt;br&gt;&lt;font color="#ff0000"&gt;&amp;nbsp; width: 863px; (Add this line)&lt;/font&gt;&lt;br&gt;&amp;nbsp; margin: 0;&lt;br&gt;&amp;nbsp; padding: 25px 60px 35px 60px;&lt;br&gt;&amp;nbsp; color: $pagetitlecolor;&lt;br&gt;&amp;nbsp; background: url(&lt;a href="http://www.blogblog.com/tictac_blue/top_h1.gif)"&gt;http://www.blogblog.com/tictac_blue/top_h1.gif)&lt;/a&gt; no-repeat bottom left;&lt;br&gt;&amp;nbsp; }  &lt;p&gt;It looks pretty easy, but it takes me a couple of hours to figure out all those tricks.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7462882-7351304239298570572?l=gisresearch.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gisresearch.blogspot.com/feeds/7351304239298570572/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7462882&amp;postID=7351304239298570572' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7462882/posts/default/7351304239298570572'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7462882/posts/default/7351304239298570572'/><link rel='alternate' type='text/html' href='http://gisresearch.blogspot.com/2007/08/changed-default-blog-template.html' title='Changed the default blog template.'/><author><name>J.W.</name><uri>http://www.blogger.com/profile/09241601264454722977</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://farm3.static.flickr.com/2116/1856041089_20ef060d43_o.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7462882.post-1687615592794093617</id><published>2007-07-10T10:15:00.001-04:00</published><updated>2007-07-10T10:15:01.762-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Asp.Net'/><title type='text'>Make the safe update in asp.net project.</title><content type='html'>&lt;p&gt;When a project gets complicated, it become increasingly challenging to make any updates to it, especially for the project which you didn't start to work with. I was put into such a situation recently. The clients require that I make a lot of changes to an existing web applications,&amp;nbsp;and they want all the new features I develop will be turned on a specific day. They also want to have the option to turn all the new features&amp;nbsp;off and keep the original state.&lt;/p&gt; &lt;p&gt;If it's all business logic changing wrapped in a dll, it should be much easier. The challenges&amp;nbsp;are that&amp;nbsp;the project&amp;nbsp;also involves a lot of user interface changes. If I try to make the individual element or control on a page visible/invisible based on certain conditions, it will become very messy and difficult to maintain in the future. For example, if the&amp;nbsp;clients want to completely get rid of all the old features, leaving all those checking codes there will be very confusing for the people who will work on the projects in the future.&lt;/p&gt; &lt;p&gt;I end up putting all the old features on a page into a user control, and all my new improvements combined with the original codes in another user control like the following&lt;a title="FeatureTurning" href="http://www.flickr.com/photos/9918938@N04/768323427/"&gt;&lt;img alt="FeatureTurning" src="http://static.flickr.com/1019/768323427_de336bb659.jpg" border="0"&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;In the code behind,&amp;nbsp;I can swap&amp;nbsp;between the old codes and new codes by setting one user control visible and the other invisible. And in the future, when the clients don't want the old features anymore, the old codes can be completely taken out.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7462882-1687615592794093617?l=gisresearch.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gisresearch.blogspot.com/feeds/1687615592794093617/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7462882&amp;postID=1687615592794093617' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7462882/posts/default/1687615592794093617'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7462882/posts/default/1687615592794093617'/><link rel='alternate' type='text/html' href='http://gisresearch.blogspot.com/2007/07/make-safe-update-in-aspnet-project.html' title='Make the safe update in asp.net project.'/><author><name>J.W.</name><uri>http://www.blogger.com/profile/09241601264454722977</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://farm3.static.flickr.com/2116/1856041089_20ef060d43_o.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7462882.post-417925886699682275</id><published>2007-06-25T20:19:00.000-04:00</published><updated>2007-07-10T09:29:40.658-04:00</updated><title type='text'></title><content type='html'>Dict.cn&lt;br&gt;&lt;br&gt;I have been using this English-Chinese dictionary website for a while, and I am really amazed with all the functionalities it provides. Traditionally, if you look up a word in the dictionary, you may forget it in the next day and have to look it up again, and the dict.cn allows you to save all your unfamiliar words into the profile. This is particular useful if you are in a learning process, you can always come back to review the words you have marked before.&lt;br&gt;&lt;br&gt;Another impressive feature is that the site has collected all the words for a particular subject, say, if you want to review all the GMAT words, you can go there and review that particular subject：&lt;br&gt;&lt;br&gt;&lt;div style="padding: 1em 0pt; text-align: left;"&gt;&lt;img style="width: 640px;" src="http://docs.google.com/File?id=dft225h8_748fkmwtfn"&gt;&lt;br&gt;&lt;br&gt;When you review a particular test, you can track all your progress in your profile, this is very cool..&lt;br&gt;&lt;/div&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7462882-417925886699682275?l=gisresearch.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gisresearch.blogspot.com/feeds/417925886699682275/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7462882&amp;postID=417925886699682275' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7462882/posts/default/417925886699682275'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7462882/posts/default/417925886699682275'/><link rel='alternate' type='text/html' href='http://gisresearch.blogspot.com/2007/06/dict.html' title=''/><author><name>J.W.</name><uri>http://www.blogger.com/profile/09241601264454722977</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://farm3.static.flickr.com/2116/1856041089_20ef060d43_o.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7462882.post-5349128949532822110</id><published>2007-05-17T15:01:00.000-04:00</published><updated>2007-05-24T16:15:34.975-04:00</updated><title type='text'></title><content type='html'> &lt;P CLASS="western" STYLE="margin-bottom: 0in"&gt;&lt;FONT FACE="Garamond, serif"&gt;SQL Reporting Service could get a little bit frustrated. (Invalid Object about temporary table.)&lt;/FONT&gt;&lt;/P&gt; &lt;P CLASS="western" STYLE="margin-bottom: 0in"&gt;&lt;BR&gt; &lt;/P&gt; &lt;P CLASS="western" STYLE="margin-bottom: 0in"&gt;&lt;FONT FACE="Garamond, serif"&gt;I am starting to use the SQL reporting service to generate a couple of reports for the project I am working on right now, and it could get a little bit frustrated for a newbie.&lt;/FONT&gt;&lt;/P&gt; &lt;P CLASS="western" STYLE="margin-bottom: 0in"&gt;&lt;BR&gt; &lt;/P&gt; &lt;P CLASS="western" STYLE="margin-bottom: 0in"&gt;&lt;FONT FACE="Garamond, serif"&gt;In my process, I need to generate a report based on a stored procedure.&lt;/FONT&gt;&lt;/P&gt; &lt;P CLASS="western" STYLE="margin-bottom: 0in"&gt;&lt;IMG SRC="http://docs.google.com/File?id=dft225h8_6069x85hhq" NAME="graphics1" ALIGN=BOTTOM WIDTH=497 HEIGHT=473 BORDER=0&gt;&lt;/P&gt; &lt;P CLASS="western" STYLE="margin-bottom: 0in"&gt;&lt;BR&gt; &lt;/P&gt; &lt;P CLASS="western" STYLE="margin-bottom: 0in"&gt;&lt;FONT FACE="Garamond, serif"&gt;Then, I got the following error which complains that the temporary table is invalid.&lt;/FONT&gt;&lt;/P&gt; &lt;P CLASS="western" STYLE="margin-bottom: 0in"&gt;&lt;IMG SRC="http://docs.google.com/File?id=dft225h8_61dw3pdjds" NAME="graphics2" ALIGN=BOTTOM WIDTH=509 HEIGHT=270 BORDER=0&gt;&lt;/P&gt; &lt;P CLASS="western" STYLE="margin-bottom: 0in"&gt;&lt;FONT FACE="Garamond, serif"&gt;What you can do, the temporary table should be perfectly fine in the stored procedure. I just clicked OK.&lt;/FONT&gt;&lt;/P&gt; &lt;P CLASS="western" STYLE="margin-bottom: 0in"&gt;&lt;BR&gt; &lt;/P&gt; &lt;P CLASS="western" STYLE="margin-bottom: 0in"&gt;&lt;FONT FACE="Garamond, serif"&gt;Since the dataset was not generated successfully, it won&amp;rsquo;t automatically generate a list of report parameters for you. &lt;/FONT&gt; &lt;/P&gt; &lt;P CLASS="western" STYLE="margin-bottom: 0in"&gt;&lt;BR&gt; &lt;/P&gt; &lt;P CLASS="western" STYLE="margin-bottom: 0in"&gt;&lt;IMG SRC="http://docs.google.com/File?id=dft225h8_62fz64ccdd" NAME="graphics3" ALIGN=BOTTOM WIDTH=512 HEIGHT=119 BORDER=0&gt;&lt;/P&gt; &lt;P CLASS="western" STYLE="margin-bottom: 0in"&gt;&lt;BR&gt; &lt;/P&gt; &lt;P CLASS="western" STYLE="margin-bottom: 0in"&gt;&lt;FONT FACE="Garamond, serif"&gt;The good thing is that unlike Crystal report which the underlying format is in binary, sql report is all xml based, which gives a lot of flexibility in editing the report manually.&lt;/FONT&gt;&lt;/P&gt; &lt;P CLASS="western" STYLE="margin-bottom: 0in"&gt;&lt;BR&gt; &lt;/P&gt; &lt;P CLASS="western" STYLE="margin-bottom: 0in"&gt;&lt;FONT FACE="Garamond, serif"&gt;You can simply manually add a list of report parameters like this in the rdl file (open it in any text editing software).&lt;/FONT&gt;&lt;/P&gt; &lt;P CLASS="western" STYLE="margin-bottom: 0in"&gt;&lt;BR&gt; &lt;/P&gt; &lt;P CLASS="western" STYLE="margin-bottom: 0in"&gt;  &lt;FONT FACE="Garamond, serif"&gt;&amp;lt;ReportParameters&amp;gt;&lt;/FONT&gt;&lt;/P&gt; &lt;P CLASS="western" STYLE="margin-bottom: 0in"&gt;    &lt;FONT FACE="Garamond, serif"&gt;&amp;lt;ReportParameter Name=&amp;quot;countyID&amp;quot;&amp;gt;&lt;/FONT&gt;&lt;/P&gt; &lt;P CLASS="western" STYLE="margin-bottom: 0in"&gt;      &lt;FONT FACE="Garamond, serif"&gt;&amp;lt;DataType&amp;gt;String&amp;lt;/DataType&amp;gt;&lt;/FONT&gt;&lt;/P&gt; &lt;P CLASS="western" STYLE="margin-bottom: 0in"&gt;      &lt;FONT FACE="Garamond, serif"&gt;&amp;lt;DefaultValue&amp;gt;&lt;/FONT&gt;&lt;/P&gt; &lt;P CLASS="western" STYLE="margin-bottom: 0in"&gt;        &lt;FONT FACE="Garamond, serif"&gt;&amp;lt;Values&amp;gt;&lt;/FONT&gt;&lt;/P&gt; &lt;P CLASS="western" STYLE="margin-bottom: 0in"&gt;          &lt;FONT FACE="Garamond, serif"&gt;&amp;lt;Value&amp;gt;e12b5415-de73-4751-b2cb-2e98740c4460&amp;lt;/Value&amp;gt;&lt;/FONT&gt;&lt;/P&gt; &lt;P CLASS="western" STYLE="margin-bottom: 0in"&gt;        &lt;FONT FACE="Garamond, serif"&gt;&amp;lt;/Values&amp;gt;&lt;/FONT&gt;&lt;/P&gt; &lt;P CLASS="western" STYLE="margin-bottom: 0in"&gt;      &lt;FONT FACE="Garamond, serif"&gt;&amp;lt;/DefaultValue&amp;gt;&lt;/FONT&gt;&lt;/P&gt; &lt;P CLASS="western" STYLE="margin-bottom: 0in"&gt;      &lt;FONT FACE="Garamond, serif"&gt;&amp;lt;Prompt&amp;gt;County ID&amp;lt;/Prompt&amp;gt;&lt;/FONT&gt;&lt;/P&gt; &lt;P CLASS="western" STYLE="margin-bottom: 0in"&gt;    &lt;FONT FACE="Garamond, serif"&gt;&amp;lt;/ReportParameter&amp;gt;&lt;/FONT&gt;&lt;/P&gt; &lt;P CLASS="western" STYLE="margin-bottom: 0in"&gt;    &lt;FONT FACE="Garamond, serif"&gt;&amp;lt;--- other report parameters&amp;gt;&lt;/FONT&gt;&lt;/P&gt; &lt;P CLASS="western" STYLE="margin-bottom: 0in"&gt;  &lt;FONT FACE="Garamond, serif"&gt;&amp;lt;/ReportParameters&amp;gt;&lt;/FONT&gt;&lt;/P&gt; &lt;P CLASS="western" STYLE="margin-bottom: 0in"&gt;&lt;BR&gt; &lt;/P&gt; &lt;P CLASS="western" STYLE="margin-bottom: 0in"&gt;&lt;FONT FACE="Garamond, serif"&gt;This will generate a list of report parameters &lt;/FONT&gt; &lt;/P&gt; &lt;P CLASS="western" STYLE="margin-bottom: 0in"&gt;&lt;IMG SRC="http://docs.google.com/File?id=dft225h8_63jvqvgphs" NAME="graphics4" ALIGN=BOTTOM WIDTH=472 HEIGHT=201 BORDER=0&gt;&lt;/P&gt; &lt;P CLASS="western" STYLE="margin-bottom: 0in"&gt;&lt;BR&gt; &lt;/P&gt; &lt;P CLASS="western" STYLE="margin-bottom: 0in"&gt;&lt;FONT FACE="Garamond, serif"&gt;But how do you pass those reporting parameters to the sql query parameters. If you put a table control on the report, and set the underlying data source to the previous dataset, and try to preview it. It will give you another error like this: &lt;/FONT&gt; &lt;/P&gt; &lt;P CLASS="western" STYLE="margin-bottom: 0in"&gt;&lt;BR&gt; &lt;/P&gt; &lt;P CLASS="western" STYLE="margin-bottom: 0in"&gt;&lt;IMG SRC="http://docs.google.com/File?id=dft225h8_64dvb9n6gf" NAME="graphics5" ALIGN=BOTTOM WIDTH=578 HEIGHT=146 BORDER=0&gt;&lt;/P&gt; &lt;P CLASS="western" STYLE="margin-bottom: 0in"&gt;&lt;BR&gt; &lt;/P&gt; &lt;P CLASS="western" STYLE="margin-bottom: 0in"&gt;&lt;BR&gt; &lt;/P&gt; &lt;P CLASS="western" STYLE="margin-bottom: 0in"&gt;&lt;FONT FACE="Garamond, serif"&gt;There are two ways to address this issue: &lt;/FONT&gt; &lt;/P&gt; &lt;OL&gt; 	&lt;LI&gt;&lt;P CLASS="western" STYLE="margin-bottom: 0in"&gt;&lt;FONT FACE="Garamond, serif"&gt;one 	way is that you go back to the dataset, set the Parameters manually 	there.&lt;/FONT&gt;&lt;/P&gt; &lt;/OL&gt; &lt;P CLASS="western" STYLE="margin-left: 0.5in; margin-bottom: 0in"&gt;&lt;IMG SRC="http://docs.google.com/File?id=dft225h8_65c6sqtkfw" NAME="graphics6" ALIGN=BOTTOM WIDTH=540 HEIGHT=430 BORDER=0&gt;&lt;/P&gt; &lt;OL START=2&gt; 	&lt;LI&gt;&lt;P CLASS="western" STYLE="margin-bottom: 0in"&gt;&lt;FONT FACE="Garamond, serif"&gt;The 	other option is that you can still edit in the xml file, which is 	the way I preferred. Under the DataSets, looking for the DataSet 	interested, and set the QueryParameters there&amp;hellip;&lt;/FONT&gt;&lt;/P&gt; &lt;/OL&gt; &lt;P CLASS="western" STYLE="margin-left: 0.5in; margin-bottom: 0in"&gt;  &lt;FONT FACE="Garamond, serif"&gt;&amp;lt;DataSets&amp;gt;&lt;/FONT&gt;&lt;/P&gt; &lt;P CLASS="western" STYLE="margin-left: 0.5in; margin-bottom: 0in"&gt;    &lt;FONT FACE="Garamond, serif"&gt;&amp;lt;DataSet Name=&amp;quot;ComplianceMissing&amp;quot;&amp;gt;&lt;/FONT&gt;&lt;/P&gt; &lt;P CLASS="western" STYLE="margin-left: 0.5in; margin-bottom: 0in"&gt;      &lt;FONT FACE="Garamond, serif"&gt;&amp;lt;Query&amp;gt;&lt;/FONT&gt;&lt;/P&gt; &lt;P CLASS="western" STYLE="margin-left: 0.5in; margin-bottom: 0in"&gt;        &lt;FONT FACE="Garamond, serif"&gt;&amp;lt;DataSourceName&amp;gt;EarlyTrack&amp;lt;/DataSourceName&amp;gt;&lt;/FONT&gt;&lt;/P&gt; &lt;P CLASS="western" STYLE="margin-left: 0.5in; margin-bottom: 0in"&gt;        &lt;FONT FACE="Garamond, serif"&gt;&amp;lt;CommandType&amp;gt;StoredProcedure&amp;lt;/CommandType&amp;gt;&lt;/FONT&gt;&lt;/P&gt; &lt;P CLASS="western" STYLE="margin-left: 0.5in; margin-bottom: 0in"&gt;        &lt;FONT FACE="Garamond, serif"&gt;&amp;lt;CommandText&amp;gt;rptGetComplianceMissingChild&amp;lt;/CommandText&amp;gt;&lt;/FONT&gt;&lt;/P&gt; &lt;P CLASS="western" STYLE="margin-left: 0.5in; margin-bottom: 0in"&gt;       &lt;FONT FACE="Garamond, serif"&gt;&amp;lt;QueryParameters&amp;gt;&lt;/FONT&gt;&lt;/P&gt; &lt;P CLASS="western" STYLE="margin-left: 0.5in; margin-bottom: 0in"&gt;          &lt;FONT FACE="Garamond, serif"&gt;&amp;lt;QueryParameter Name=&amp;quot;@countyID&amp;quot;&amp;gt;&lt;/FONT&gt;&lt;/P&gt; &lt;P CLASS="western" STYLE="margin-left: 0.5in; margin-bottom: 0in"&gt;          &lt;FONT FACE="Garamond, serif"&gt;&amp;lt;/QueryParameter&amp;gt;&lt;/FONT&gt;&lt;/P&gt; &lt;P CLASS="western" STYLE="margin-left: 0.5in; margin-bottom: 0in"&gt;        &lt;FONT FACE="Garamond, serif"&gt;&amp;lt;/QueryParameters&amp;gt;        &lt;/FONT&gt; &lt;/P&gt; &lt;P CLASS="western" STYLE="margin-left: 0.5in; margin-bottom: 0in"&gt;      &lt;FONT FACE="Garamond, serif"&gt;&amp;lt;/Query&amp;gt;&lt;/FONT&gt;&lt;/P&gt; &lt;P CLASS="western" STYLE="margin-left: 0.5in; margin-bottom: 0in"&gt;    &lt;FONT FACE="Garamond, serif"&gt;&amp;lt;/DataSet&amp;gt;&lt;/FONT&gt;&lt;/P&gt; &lt;P CLASS="western" STYLE="margin-left: 0.5in; margin-bottom: 0in"&gt;  &lt;FONT FACE="Garamond, serif"&gt;&amp;lt;/DataSets&amp;gt;&lt;/FONT&gt;&lt;/P&gt; &lt;P CLASS="western" STYLE="margin-left: 0.5in; margin-bottom: 0in"&gt;&lt;BR&gt; &lt;/P&gt; &lt;P CLASS="western" STYLE="margin-left: 0.5in; margin-bottom: 0in"&gt;&lt;BR&gt; &lt;/P&gt; &lt;P CLASS="western" STYLE="margin-left: 0.5in; margin-bottom: 0in"&gt;&lt;FONT FACE="Garamond, serif"&gt;The whole process is not that trival&amp;hellip;&lt;/FONT&gt;&lt;/P&gt; &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7462882-5349128949532822110?l=gisresearch.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gisresearch.blogspot.com/feeds/5349128949532822110/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7462882&amp;postID=5349128949532822110' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7462882/posts/default/5349128949532822110'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7462882/posts/default/5349128949532822110'/><link rel='alternate' type='text/html' href='http://gisresearch.blogspot.com/2007/05/sql-reporting-service-could-get-little.html' title=''/><author><name>J.W.</name><uri>http://www.blogger.com/profile/09241601264454722977</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://farm3.static.flickr.com/2116/1856041089_20ef060d43_o.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7462882.post-3901393469930509781</id><published>2007-05-17T13:41:00.000-04:00</published><updated>2007-05-17T13:51:47.392-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Visual Studio'/><title type='text'></title><content type='html'>   &lt;p class="western" style="margin-bottom: 0in;"&gt;&lt;b&gt;&lt;font style="font-size: 20pt;" size="5"&gt;&lt;font face="Arial, sans-serif"&gt;Integrate Visual Studio 2003 with the Team Foundation Server Process&lt;/font&gt;&lt;/font&gt;&lt;/b&gt;&lt;/p&gt; &lt;p class="western" style="margin-bottom: 0in;"&gt;&lt;br&gt; &lt;/p&gt; &lt;p class="western" style="margin-left: 0.25in; margin-bottom: 0in;"&gt;&lt;font face="Arial, sans-serif"&gt;The Team foundation server is release by Microsoft after Visual studio 2003, so the visual studio 2003 has to go through a couple of manual configuration process to be able to work with Team Foundation Server.&lt;/font&gt;&lt;/p&gt; &lt;p class="western" style="margin-left: 0.25in; margin-bottom: 0in;"&gt;&lt;br&gt; &lt;/p&gt; &lt;ol&gt; 	&lt;li&gt;&lt;p class="western" style="margin-bottom: 0in;"&gt;&lt;font face="Arial, sans-serif"&gt;Download 	“&lt;/font&gt;&lt;font color="#0000ff"&gt;&lt;u&gt;&lt;a href="http://www.microsoft.com/downloads/details.aspx?familyid=87E1FFBD-A484-4C3A-8776-D560AB1E6198&amp;amp;displaylang=en"&gt;&lt;font face="Arial, sans-serif"&gt;Visual 	Studio 2005 Team Foundation Server MSSCCI Provider&lt;/font&gt;&lt;/a&gt;&lt;/u&gt;&lt;/font&gt;&lt;font face="Arial, sans-serif"&gt;” 	from Microsoft Website.  (The download link could change in the 	future, it’s best to download a copy and store it on some 	place on the server). &lt;/font&gt; 	&lt;/p&gt; 	&lt;/li&gt;&lt;li&gt;&lt;p class="western" style="margin-bottom: 0in;"&gt;&lt;font face="Arial, sans-serif"&gt;The 	prerequisite to this installation is that you must already have:&lt;/font&gt;&lt;/p&gt; 	&lt;ol&gt; 		&lt;li&gt;&lt;p class="western" style="margin-bottom: 0in;"&gt;&lt;font face="Tahoma, sans-serif"&gt;Visual 		Studio 2005 Team Foundation Server&lt;/font&gt;&lt;/p&gt; 		&lt;/li&gt;&lt;li&gt;&lt;p class="western" style="margin-bottom: 0in;"&gt;&lt;font face="Tahoma, sans-serif"&gt;Visual 		Studio 2005 Team Explorer&lt;/font&gt;&lt;/p&gt; 		&lt;/li&gt;&lt;li&gt;&lt;p class="western" style="margin-bottom: 0in;"&gt;&lt;font face="Tahoma, sans-serif"&gt;.NET 		Framework 2.0&lt;/font&gt;&lt;/p&gt; 	&lt;/li&gt;&lt;/ol&gt; &lt;/li&gt;&lt;/ol&gt; &lt;p class="western" style="margin-left: 1in; margin-bottom: 0in;"&gt;&lt;br&gt; &lt;/p&gt; &lt;p class="western" style="margin-left: 1in; margin-bottom: 0in;"&gt;&lt;font face="Tahoma, sans-serif"&gt;If you already work with Team Foundation Server with the Visual Studio 2005, you should already have those program installed.&lt;/font&gt;&lt;/p&gt; &lt;p class="western" style="margin-left: 1in; margin-bottom: 0in;"&gt;&lt;br&gt; &lt;/p&gt; &lt;ol start="3"&gt; 	&lt;li&gt;&lt;p class="western" style="margin-bottom: 0in;"&gt;&lt;font face="Tahoma, sans-serif"&gt;To 	add an existing project to the Team Foundation Server, Right Click 	the Solution you want to add to the Team Foundation Server, and 	click “Add solution to source control”.&lt;/font&gt;&lt;/p&gt; &lt;/li&gt;&lt;/ol&gt; &lt;div style="padding: 1em 0pt; text-align: left;"&gt;&lt;img src="http://docs.google.com/File?id=dft225h8_56ccq2hfdw"&gt;&lt;/div&gt; &lt;p class="western" style="margin-bottom: 0in;"&gt;&lt;br&gt; &lt;/p&gt; &lt;ol start="4"&gt; 	&lt;li&gt;&lt;p class="western" style="margin-bottom: 0in;"&gt;&lt;font face="Tahoma, sans-serif"&gt;Select 	the Tfs server you want to connect to: (If it’s the first time 	you connect to the Tfs server, you have to type in the Tfs server 	name you want to connect to.)&lt;/font&gt;&lt;/p&gt; &lt;/li&gt;&lt;/ol&gt; &lt;div style="padding: 1em 0pt; text-align: left;"&gt;&lt;img src="http://docs.google.com/File?id=dft225h8_57rd69w9pq"&gt;&lt;/div&gt; &lt;p class="western" style="margin-bottom: 0in;"&gt;&lt;br&gt; &lt;/p&gt; &lt;ol start="5"&gt; 	&lt;li&gt;&lt;p class="western" style="margin-bottom: 0in;"&gt;&lt;font face="Arial, sans-serif"&gt;Add 	the project to the Tfs Server.&lt;/font&gt;&lt;/p&gt; &lt;/li&gt;&lt;/ol&gt; &lt;div style="padding: 1em 0pt; text-align: left;"&gt;&lt;img src="http://docs.google.com/File?id=dft225h8_58cm2zn9dd"&gt;&lt;/div&gt; &lt;p class="western" style="margin-bottom: 0in;"&gt;&lt;br&gt; &lt;/p&gt; &lt;ol start="6"&gt; 	&lt;li&gt;&lt;p class="western" style="margin-bottom: 0in;"&gt;&lt;font face="Arial, sans-serif"&gt;After 	adding the project, you can see all the icons turned to “checked 	in” status.&lt;/font&gt;&lt;/p&gt; &lt;/li&gt;&lt;/ol&gt; &lt;p class="western" style="margin-left: 0.75in; margin-bottom: 0in;"&gt;&lt;img src="http://docs.google.com/File?id=dft225h8_55hgcbc6gt" name="graphics4" align="bottom" border="0" height="229" width="395"&gt;&lt;/p&gt; &lt;ol start="7"&gt; 	&lt;li&gt;&lt;p class="western" style="margin-bottom: 0in;"&gt; &lt;font face="Arial, sans-serif"&gt;You 	can also go to File -&amp;gt; Source Control to add an existing project 	to the solution.&lt;/font&gt;&lt;/p&gt; &lt;/li&gt;&lt;/ol&gt; &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7462882-3901393469930509781?l=gisresearch.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gisresearch.blogspot.com/feeds/3901393469930509781/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7462882&amp;postID=3901393469930509781' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7462882/posts/default/3901393469930509781'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7462882/posts/default/3901393469930509781'/><link rel='alternate' type='text/html' href='http://gisresearch.blogspot.com/2007/05/integrate-visual-studio-2003-with-team.html' title=''/><author><name>J.W.</name><uri>http://www.blogger.com/profile/09241601264454722977</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://farm3.static.flickr.com/2116/1856041089_20ef060d43_o.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7462882.post-6078324960484878781</id><published>2007-05-05T11:00:00.000-04:00</published><updated>2007-05-17T13:29:03.442-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='.Net'/><title type='text'></title><content type='html'>    What Http Modules are configured in the machine.config .&lt;br&gt;&lt;br&gt;I am looking into an issue what happens if you forgot to put any session configuration in the web.config file. The session state is one of the http modules configured in the machine.config file, there are a few besides the session state module. The following is what I found in my machine.config file. &lt;br&gt;&lt;br&gt;&lt;br&gt;        &amp;lt;httpModules&amp;gt;&lt;br&gt;            &amp;lt;add name="OutputCache" type="System.Web.Caching.OutputCacheModule" /&amp;gt;&lt;br&gt;            &amp;lt;add name="Session" type="System.Web.SessionState.SessionStateModule" /&amp;gt;&lt;br&gt;            &amp;lt;add name="WindowsAuthentication" type="System.Web.Security.WindowsAuthenticationModule" /&amp;gt;&lt;br&gt;            &amp;lt;add name="FormsAuthentication" type="System.Web.Security.FormsAuthenticationModule" /&amp;gt;&lt;br&gt;            &amp;lt;add name="PassportAuthentication" type="System.Web.Security.PassportAuthenticationModule" /&amp;gt;&lt;br&gt;            &amp;lt;add name="RoleManager" type="System.Web.Security.RoleManagerModule" /&amp;gt;&lt;br&gt;            &amp;lt;add name="UrlAuthorization" type="System.Web.Security.UrlAuthorizationModule" /&amp;gt;&lt;br&gt;            &amp;lt;add name="FileAuthorization" type="System.Web.Security.FileAuthorizationModule" /&amp;gt;&lt;br&gt;            &amp;lt;add name="AnonymousIdentification" type="System.Web.Security.AnonymousIdentificationModule" /&amp;gt;&lt;br&gt;            &amp;lt;add name="Profile" type="System.Web.Profile.ProfileModule" /&amp;gt;&lt;br&gt;            &amp;lt;add name="ErrorHandlerModule" type="System.Web.Mobile.ErrorHandlerModule, System.Web.Mobile, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" /&amp;gt;&lt;br&gt;        &amp;lt;/httpModules&amp;gt;&lt;br&gt;&lt;br&gt;Basically, when the Http application starts,  it will loop through all the http modules which are configured. &lt;img style="height: 183px; width: 693px;" src="http://docs.google.com/File?id=dft225h8_48dx5nfwfw"&gt;&lt;br&gt;&lt;br&gt;And SessionStateModule is one of them, and if you look into what SessionStateModule.Init() actually does. which in turn will call InitModuleFromConfig.&lt;br&gt;&lt;br&gt;&lt;img style="height: 711px; width: 712px;" src="http://docs.google.com/File?id=dft225h8_49f4f2brgj"&gt;&lt;br&gt;&lt;br&gt;Notice that &lt;a title="System.Web.Configuration.SessionStateSection" href="http://www.aisto.com/roeder/dotnet/Default.aspx?Target=code://System.Web:2.0.0.0:b03f5f7f11d50a3a/System.Web.Configuration.SessionStateSection"&gt;SessionStateSection&lt;/a&gt; &lt;b&gt;config&lt;/b&gt; = &lt;a title="System.Web.Configuration.RuntimeConfig" href="http://www.aisto.com/roeder/dotnet/Default.aspx?Target=code://System.Web:2.0.0.0:b03f5f7f11d50a3a/System.Web.Configuration.RuntimeConfig"&gt;RuntimeConfig&lt;/a&gt;.&lt;a title="RuntimeConfig System.Web.Configuration.RuntimeConfig.GetAppConfig();" href="http://www.aisto.com/roeder/dotnet/Default.aspx?Target=code://System.Web:2.0.0.0:b03f5f7f11d50a3a/System.Web.Configuration.RuntimeConfig/GetAppConfig%28%29:System.Web.Configuration.RuntimeConfig"&gt;GetAppConfig&lt;/a&gt;().&lt;a title="SessionStateSection System.Web.Configuration.RuntimeConfig.SessionState { ... }" href="http://www.aisto.com/roeder/dotnet/Default.aspx?Target=code://System.Web:2.0.0.0:b03f5f7f11d50a3a/System.Web.Configuration.RuntimeConfig/property:SessionState:System.Web.Configuration.SessionStateSection"&gt;SessionState&lt;/a&gt;;&lt;br&gt;&lt;br&gt;And here is what it does in &lt;a title="System.Web.Configuration.RuntimeConfig" href="http://www.aisto.com/roeder/dotnet/Default.aspx?Target=code://System.Web:2.0.0.0:b03f5f7f11d50a3a/System.Web.Configuration.RuntimeConfig"&gt;RuntimeConfig&lt;/a&gt;.&lt;a title="RuntimeConfig System.Web.Configuration.RuntimeConfig.GetAppConfig();" href="http://www.aisto.com/roeder/dotnet/Default.aspx?Target=code://System.Web:2.0.0.0:b03f5f7f11d50a3a/System.Web.Configuration.RuntimeConfig/GetAppConfig%28%29:System.Web.Configuration.RuntimeConfig"&gt;GetAppConfig&lt;/a&gt;().&lt;a title="SessionStateSection System.Web.Configuration.RuntimeConfig.SessionState { ... }" href="http://www.aisto.com/roeder/dotnet/Default.aspx?Target=code://System.Web:2.0.0.0:b03f5f7f11d50a3a/System.Web.Configuration.RuntimeConfig/property:SessionState:System.Web.Configuration.SessionStateSection"&gt;SessionState&lt;/a&gt;.&lt;br&gt;&lt;br&gt;&lt;table style="margin-bottom: 0px;" cellpadding="0" cellspacing="0" width="100%"&gt; &lt;tbody&gt; &lt;tr&gt; &lt;td style="padding: 4px 5px;" colspan="2" valign="top"&gt;&lt;pre&gt;&lt;font color="#1000a0"&gt;internal&lt;/font&gt; &lt;a title="System.Web.Configuration.SessionStateSection" href="http://www.aisto.com/roeder/dotnet/Default.aspx?Target=code://System.Web:2.0.0.0:b03f5f7f11d50a3a/System.Web.Configuration.SessionStateSection"&gt;SessionStateSection&lt;/a&gt; &lt;b&gt;&lt;a class="bold" href="http://www.aisto.com/roeder/dotnet/Default.aspx?Target=code://System.Web:2.0.0.0:b03f5f7f11d50a3a/System.Web.Configuration.RuntimeConfig/property:SessionState:System.Web.Configuration.SessionStateSection"&gt;SessionState&lt;/a&gt;&lt;/b&gt;&lt;br&gt;{&lt;br&gt;    &lt;font color="#1000a0"&gt;get&lt;/font&gt;&lt;br&gt;    {&lt;br&gt;        &lt;font color="#1000a0"&gt;return&lt;/font&gt; (&lt;a title="System.Web.Configuration.SessionStateSection" href="http://www.aisto.com/roeder/dotnet/Default.aspx?Target=code://System.Web:2.0.0.0:b03f5f7f11d50a3a/System.Web.Configuration.SessionStateSection"&gt;SessionStateSection&lt;/a&gt;) &lt;font color="#1000a0"&gt;this&lt;/font&gt;.&lt;a title="object System.Web.Configuration.RuntimeConfig.GetSection(string sectionName, Type type);" href="http://www.aisto.com/roeder/dotnet/Default.aspx?Target=code://System.Web:2.0.0.0:b03f5f7f11d50a3a/System.Web.Configuration.RuntimeConfig/GetSection%28String,System.Type%29:Object"&gt;GetSection&lt;/a&gt;(&lt;font color="#800000"&gt;"system.web/sessionState"&lt;/font&gt;, &lt;font color="#1000a0"&gt;typeof&lt;/font&gt;(&lt;a title="System.Web.Configuration.SessionStateSection" href="http://www.aisto.com/roeder/dotnet/Default.aspx?Target=code://System.Web:2.0.0.0:b03f5f7f11d50a3a/System.Web.Configuration.SessionStateSection"&gt;SessionStateSection&lt;/a&gt;));&lt;br&gt;    }&lt;br&gt;}&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt; &lt;table style="margin-bottom: 0px;" cellpadding="0" cellspacing="0" width="100%"&gt; &lt;tbody&gt; &lt;tr&gt; &lt;td style="padding: 4px 5px;" colspan="2" valign="top"&gt;&lt;br&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;Here is what it actually tried to read the section from &lt;font&gt;&lt;font color="#800000"&gt;&lt;span style="font-family: monospace;"&gt;"&lt;/span&gt;system.web/sessionState", &lt;/font&gt;&lt;/font&gt;but what if this section is missing, it will default all its values to default value of SessionStateSeciton. This is just my guessing, I tried to verify it through reflector, but the code is kind of confusing to me. When you cannot step through the code through debugger, you can only step through your code through your head. It becomes a little bit confusing..&lt;br&gt;&lt;br&gt;Here is what I see the SessionStateSection in the reflector..&lt;br&gt;&lt;img style="height: 485px; width: 778px;" src="http://docs.google.com/File?id=dft225h8_50c5kksndn"&gt;&lt;br&gt;&lt;br&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7462882-6078324960484878781?l=gisresearch.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gisresearch.blogspot.com/feeds/6078324960484878781/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7462882&amp;postID=6078324960484878781' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7462882/posts/default/6078324960484878781'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7462882/posts/default/6078324960484878781'/><link rel='alternate' type='text/html' href='http://gisresearch.blogspot.com/2007/05/what-http-modules-are-configured-in.html' title=''/><author><name>J.W.</name><uri>http://www.blogger.com/profile/09241601264454722977</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://farm3.static.flickr.com/2116/1856041089_20ef060d43_o.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7462882.post-7955647256788390089</id><published>2007-04-25T21:44:00.000-04:00</published><updated>2007-05-17T13:29:03.443-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='.Net'/><title type='text'></title><content type='html'>  Set up the Database Trace Listener in Enterprise Library.&lt;br&gt;&lt;br&gt;I am getting very interested in Microsoft Enterprise Library lately for a couple of reasons:&lt;br&gt;&lt;ul&gt;&lt;li&gt;It addresses a couple of common issues you will normally face, like logging, caching, and you really don't want to do those plumbing code if possible.&lt;/li&gt;&lt;li&gt;It gives you a nice configuration tool ( you can open this tool within visual studio for the Enterprise Library 3) .&lt;/li&gt;&lt;li&gt;It gives you all the source code, so you can see what's under the hood.&lt;/li&gt;&lt;/ul&gt;I am playing with the Logging application block in last two days, the best way to learn those tools is always to check the QuickStart source code. I found the quick start doesn't provide an example to show you how you can log the error into the database, which I believe is the most used cases in the system.&lt;br&gt;&lt;br&gt;I did a brief research, and you actually have to reference another dll (Microsoft.Practices.EnterpriseLibrary.Logging.Database.dll)  in order to be able to log into the database.&lt;br&gt;&lt;br&gt;Basically, you have to do the following steps : &lt;br&gt;1.  The "Microsoft.Practices.EnterpriseLibrary.Logging.Database.dll" has to be referenced.&lt;br&gt;2.  The scripts under "C:EntLib3SrcApp BlocksSrcLoggingTraceListenersDatabaseScripts" has to be run against the database to create the necessary tables and objects.&lt;br&gt;3.  The "Database Trace Listener" has to be added to the "Trace Listeners".  For the trace listener, you have to specify the Formatter, otherwise, you will get an error.&lt;br&gt;4.  Put the "Trace Listener" under the Category you want to log.&lt;br&gt;&lt;br&gt;Here is a screenshot of the configuration file..&lt;br&gt;&lt;br&gt;&lt;img style="height: 568px; width: 281px;" title="Enterpirse Configuration" src="http://docs.google.com/File?id=dft225h8_46c75k2dvd"&gt;&lt;br&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7462882-7955647256788390089?l=gisresearch.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gisresearch.blogspot.com/feeds/7955647256788390089/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7462882&amp;postID=7955647256788390089' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7462882/posts/default/7955647256788390089'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7462882/posts/default/7955647256788390089'/><link rel='alternate' type='text/html' href='http://gisresearch.blogspot.com/2007/04/set-up-database-trace-listener-in.html' title=''/><author><name>J.W.</name><uri>http://www.blogger.com/profile/09241601264454722977</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://farm3.static.flickr.com/2116/1856041089_20ef060d43_o.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7462882.post-6622879247619133017</id><published>2007-04-21T22:52:00.000-04:00</published><updated>2007-05-17T13:29:10.221-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='SQL'/><title type='text'></title><content type='html'>  Try to avoid sql generated names if you want to use change scripts to do the database upgrade.&lt;br&gt;&lt;br&gt;Sometime, if you don't explicitly name an object when you create an object in sql server, the sql server will create a default name for you. It is not too bad if you have some sophisticated tool to migrate your database. But if you want to run your change scripts manually , it's best that you name every object you created, not relying on the system generated name.&lt;br&gt;&lt;br&gt;One way to create an object in the sql server is normally dropping it firstly, that's where I got hit when relying on the system generated name. &lt;br&gt;&lt;br&gt;I have an sql script like this:&lt;br&gt;&lt;br style="color: rgb(51, 102, 255);"&gt;&lt;span style="color: rgb(51, 102, 255);"&gt;IF dbo.ColumnAlreadyExists('BusinessCategory','IsActive')=1 &lt;/span&gt;&lt;br style="color: rgb(51, 102, 255);"&gt;&lt;span style="color: rgb(51, 102, 255);"&gt;BEGIN&lt;/span&gt;&lt;br style="color: rgb(51, 102, 255);"&gt;&lt;span style="color: rgb(51, 102, 255);"&gt;ALTER TABLE BusinessCategory DROP COLUMN IsActive&lt;/span&gt;&lt;br style="color: rgb(51, 102, 255);"&gt;&lt;span style="color: rgb(51, 102, 255);"&gt;END&lt;/span&gt;&lt;br style="color: rgb(51, 102, 255);"&gt;&lt;br style="color: rgb(51, 102, 255);"&gt;&lt;span style="color: rgb(51, 102, 255);"&gt;ALTER TABLE BusinessCategory ADD IsActive Bit DEFAULT 1 &lt;/span&gt;&lt;br&gt;&lt;br&gt;It's fine when I ran it the first time, it generated the new column for me, but when I ran it again, it complains there is a  default constraint object on the IsActive column which needed to be dropped firstly.  The issue is the system generated a long name for my default constraint. The name is long, hard to remember, and could be changing, so it makes the changes scripts hard to write. &lt;br&gt;&lt;br&gt;So, the better way is to use a named object instead like this:&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;span style="color: rgb(102, 102, 204);"&gt;ALTER TABLE BusinessCategory ADD IsActive Bit&lt;/span&gt;&lt;br style="color: rgb(102, 102, 204);"&gt;&lt;span style="color: rgb(102, 102, 204);"&gt;GO&lt;/span&gt;&lt;br style="color: rgb(102, 102, 204);"&gt;&lt;span style="color: rgb(102, 102, 204);"&gt;ALTER TABLE BusinessCategory ADD CONSTRAINT BusinessCategory_Default DEFAULT 1 FOR IsActive&lt;/span&gt;&lt;br style="color: rgb(102, 102, 204);"&gt;&lt;span style="color: rgb(102, 102, 204);"&gt;GO&lt;br&gt;&lt;br&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;That way, you can always drop the named constraint if you want to drop it like this:&lt;br&gt;&lt;br style="color: rgb(102, 51, 255);"&gt;&lt;span style="color: rgb(102, 51, 255);"&gt;IF dbo.ColumnAlreadyExists('BusinessCategory','IsActive')=1 &lt;/span&gt;&lt;br style="color: rgb(102, 51, 255);"&gt;&lt;span style="color: rgb(102, 51, 255);"&gt;BEGIN&lt;/span&gt;&lt;br style="color: rgb(102, 51, 255);"&gt;&lt;span style="color: rgb(102, 51, 255);"&gt;ALTER TABLE BusinessCategory DROP CONSTRAINT BusinessCategory_Default&lt;/span&gt;&lt;br style="color: rgb(102, 51, 255);"&gt;&lt;span style="color: rgb(102, 51, 255);"&gt;ALTER TABLE BusinessCategory DROP COLUMN IsActive&lt;/span&gt;&lt;br style="color: rgb(102, 51, 255);"&gt;&lt;span style="color: rgb(102, 51, 255);"&gt;END&lt;/span&gt;&lt;br&gt;&lt;/span&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7462882-6622879247619133017?l=gisresearch.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gisresearch.blogspot.com/feeds/6622879247619133017/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7462882&amp;postID=6622879247619133017' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7462882/posts/default/6622879247619133017'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7462882/posts/default/6622879247619133017'/><link rel='alternate' type='text/html' href='http://gisresearch.blogspot.com/2007/04/try-to-avoid-sql-generated-names-if-you.html' title=''/><author><name>J.W.</name><uri>http://www.blogger.com/profile/09241601264454722977</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://farm3.static.flickr.com/2116/1856041089_20ef060d43_o.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7462882.post-7850876061053117721</id><published>2007-04-11T22:46:00.000-04:00</published><updated>2007-04-14T10:01:00.364-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Asp.Net'/><category scheme='http://www.blogger.com/atom/ns#' term='.Net'/><title type='text'></title><content type='html'>    The debugger may cheat you on cache.&lt;br&gt;&lt;br&gt;Cache is pretty tricky to work with. On one side, you have to use it to improve the performance of your application, On the other side, cache is very tricky to work with and needs careful consideration when putting it into your application.&lt;br&gt;&lt;br&gt;I recently works on a state government project which uses a lot of cache in the application. Simply put, it uses a static class to cache a lot of lookup tables. One simple example is like this:&lt;br&gt;&lt;br&gt;public static class Cache&lt;br&gt;{&lt;br&gt;    public LookupTable TestTypes&lt;br&gt;    {&lt;br&gt;         if(HttpRunTime.Cache["TestTypes"]==null)&lt;br&gt;        {&lt;br&gt;                HttpRunTime.Cache.Insert("TestTypes", CreateTestTypes(), SqlDependency);&lt;br&gt;         }&lt;br&gt;        return HttpRunTime.Cache["TestTypes"];&lt;br&gt;    }&lt;br&gt;}&lt;br&gt;&lt;br&gt;This code looks perfect, but it throws out mysterious exceptions a lot of times.&lt;br&gt;&lt;br&gt;There are two issues here:&lt;br&gt;&lt;br&gt;1&amp;gt; Don't run HttpRunTime.Cache["TestTypes"] twice, even HttpRunTime.Cache["TestTypes"]==null returns false, when you actually gets the value from HttpRunTime.Cache["TestTypes"], it could be reevaluated and return null.&lt;br&gt;2&amp;gt; Even you insert HttpRunTime.Cache.Insert("TestTypes", CreateTestTypes(), SqlDependency) here, the insertion may fail, say, there is an out of memory situation, you cannot gurantee HttpRunTime.Cache["TestTypes"] is not null.&lt;br&gt;&lt;br&gt;LookupTable lookupTable=Cache.TestTypes; If you assert the value returned by the lookupTable is not equal to null, like this: Debug.Assert(lookupTable!=null), you will see a strange phenomena when the debugger stops at this point: the lookupTable is null, but the right side of the expression is NOT null. &lt;br&gt;&lt;br&gt;This is because the Cache.TestTypes is reevaluated by the debugger, and its value is not the same value when the code executes, which was NULL. I know it's a little bit confusing. When you put the Cache.TestTypes in the watcher window, the debugger actually checks if HttpRunTime.Cache["TestTypes"] is null again. And if it is, it will insert the value into the cache again.&lt;br&gt;&lt;br&gt;A more robust way is handle the cache like this:&lt;br&gt;&lt;br&gt;public static class Cache&lt;br&gt; {&lt;br&gt;     public LookupTable TestTypes&lt;br&gt;     {&lt;br&gt;        TestTypes testTypes= HttpRunTime.Cache["TestTypes"];&lt;br&gt;        if(testTypes==null)&lt;br&gt;       {&lt;br&gt;             testTypes=CreateTestTypes();&lt;br&gt;            HttpRunTime.Cache.Insert("TestTypes", testTypes, SqlDependency);&lt;br&gt;        }&lt;br&gt;       return testTypes;&lt;br&gt;    }&lt;br&gt; }&lt;br&gt; &lt;br&gt;References:&lt;br&gt;1.  K. Scott Allen  &lt;a title="Wierd Caching" href="http://odetocode.com/Blogs/scott/archive/2006/01/29/2805.aspx"&gt;Wierd Caching&lt;/a&gt; &lt;br&gt;2.  Peter Johnson  &lt;a title="HttpRuntime.Cache vs. HttpContext.Current.Cache" href="http://weblogs.asp.net/pjohnson/archive/2006/02/06/437559.aspx"&gt;HttpRuntime.Cache vs. HttpContext.Current.Cache&lt;/a&gt;   &lt;br&gt;3. 蝈蝈俊.net &lt;a title="HttpRuntime.Cache vs. HttpContext.Current.Cache" href="http://blog.joycode.com/ghj/archive/2006/07/17/78818.aspx"&gt;HttpRuntime.Cache vs. HttpContext.Current.Cache&lt;/a&gt; &lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7462882-7850876061053117721?l=gisresearch.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gisresearch.blogspot.com/feeds/7850876061053117721/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7462882&amp;postID=7850876061053117721' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7462882/posts/default/7850876061053117721'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7462882/posts/default/7850876061053117721'/><link rel='alternate' type='text/html' href='http://gisresearch.blogspot.com/2007/04/debugger-may-cheat-you-on-cache.html' title=''/><author><name>J.W.</name><uri>http://www.blogger.com/profile/09241601264454722977</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://farm3.static.flickr.com/2116/1856041089_20ef060d43_o.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7462882.post-8163648640604622625</id><published>2007-04-08T22:12:00.000-04:00</published><updated>2007-04-11T22:47:59.332-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Programming'/><title type='text'></title><content type='html'> As you know, you have to go to war with the Army you have, not the Army you want,"&lt;br&gt;&lt;br&gt;This is what Rumsfeld said. I am sure this infamous saying also played a rule for his step down as Secretary of Defense. But I guess it also applies to a lot of developers like us. As a developer, you normally don't have the option to choose the best tools you have because you are the money maker, but NOT the money decision maker.&lt;br&gt;&lt;br&gt;In the company worked before, we use visual studio professional to develop some performance sensitive application (GIS). The application involves a lot of graphics rendering, geometry processing, some real hard-core algorithm. We encounter some performance issue, and really would like some professional tools to profile it. But again, we cannot make the decision, because the visual studio team edition costs much more than the professional edition.&lt;br&gt;&lt;br&gt;Now, I am working on Team Edition for software developer on my new job, but my current job uses so much database functionality, and I really hope I can have Team Suite, which contains the database piece of the Team edition. But again, I cannot make that decision.&lt;br&gt;&lt;br&gt;Sometimes, as a developer, you just have to work the best with what you have. If you cannot make a decision or persuade the management to make a decision to offer sophisticated tools for you, just try to find some open source, or free tools.&lt;br&gt;&lt;br&gt;Sometimes, you may have to go back to use some old fashion command way to finish your stuff. &lt;br&gt;&lt;br&gt;I really hope I, as a developer, have more right in the company to decide what tools I want to use.&lt;br&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7462882-8163648640604622625?l=gisresearch.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gisresearch.blogspot.com/feeds/8163648640604622625/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7462882&amp;postID=8163648640604622625' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7462882/posts/default/8163648640604622625'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7462882/posts/default/8163648640604622625'/><link rel='alternate' type='text/html' href='http://gisresearch.blogspot.com/2007/04/as-you-know-you-have-to-go-to-war-with.html' title=''/><author><name>J.W.</name><uri>http://www.blogger.com/profile/09241601264454722977</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://farm3.static.flickr.com/2116/1856041089_20ef060d43_o.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7462882.post-5167970682858586029</id><published>2007-04-07T23:51:00.000-04:00</published><updated>2007-04-08T20:21:46.802-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Tools'/><title type='text'></title><content type='html'>  Another google impressive product-&lt;a title="google pin yin" href="http://tools.google.com/pinyin/"&gt;google pin yin&lt;/a&gt;.&lt;br&gt;&lt;br&gt;For people who don't type chinese , it may be a little bit hard to understand. A lot of chinese people had hard time to input chinese like me. It's not because there is no good input tools, I know, there are a few very good input tools available. But to use those tools efficiently, you have to be very good at "pin yin".  A lot of people like me spoke a dialect which is far away from standard mandarin, which is most input methods are based upon.  The following is a fuzzy logic that google uses to make sure those non-standard speaker could have a decent input speed.&lt;br&gt;&lt;br&gt;&lt;img style="height: 268px; width: 275px;" src="http://docs.google.com/File?id=dft225h8_36d2r2wf"&gt;&lt;br&gt;For myself, I am terrible at mixing some of them, like those pairs (an-ang, en=eng).&lt;br&gt;&lt;br&gt;Another good feature is that you can have google store your selection patter on the server, so, it can automatically retrieve your selection next time. A good example, when I type my name, I put jianwei, and it will put my name as the first choice, because it remembered my choice of the last time.&lt;br&gt;&lt;img style="height: 111px; width: 779px;" src="http://docs.google.com/File?id=dft225h8_382xcxjr"&gt;&lt;br&gt;&lt;br&gt;I am waiting for another impressive product from google...&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7462882-5167970682858586029?l=gisresearch.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gisresearch.blogspot.com/feeds/5167970682858586029/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7462882&amp;postID=5167970682858586029' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7462882/posts/default/5167970682858586029'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7462882/posts/default/5167970682858586029'/><link rel='alternate' type='text/html' href='http://gisresearch.blogspot.com/2007/04/another-google-impressive-product.html' title=''/><author><name>J.W.</name><uri>http://www.blogger.com/profile/09241601264454722977</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://farm3.static.flickr.com/2116/1856041089_20ef060d43_o.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7462882.post-7549830680973166959</id><published>2007-03-22T22:25:00.001-04:00</published><updated>2007-04-08T10:28:01.612-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='SQL'/><title type='text'>Visual Studio Database Project.</title><content type='html'>&lt;p&gt;Visual studio 2005 has a lot of project templates when you choose to create a new project. I used mostly library project, windows form project, web project. &lt;/p&gt; &lt;p&gt;The one I used today is visual studio database project. I worked on a state government&amp;nbsp;project which uses a lot of tables, stored procedures. &lt;/p&gt; &lt;p&gt;The database project will allow me to organize all my queries, scripts, stored procedures into one project. It's very neat. Before I started to use that project, I cannot organize all my database scripts very well.&amp;nbsp; I normally keep all my scripts in one file, and copy one or another to the sql query analyzer. Then I get confused when I have a lot of scripts. &lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7462882-7549830680973166959?l=gisresearch.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gisresearch.blogspot.com/feeds/7549830680973166959/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7462882&amp;postID=7549830680973166959' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7462882/posts/default/7549830680973166959'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7462882/posts/default/7549830680973166959'/><link rel='alternate' type='text/html' href='http://gisresearch.blogspot.com/2007/03/visual-studio-database-project.html' title='Visual Studio Database Project.'/><author><name>J.W.</name><uri>http://www.blogger.com/profile/09241601264454722977</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://farm3.static.flickr.com/2116/1856041089_20ef060d43_o.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7462882.post-7278230182561233467</id><published>2007-03-20T22:26:00.000-04:00</published><updated>2007-03-20T22:34:56.910-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='.Net'/><title type='text'>Stored procedure debugging error.</title><content type='html'>I keep getting the following error when debugging a store&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp1.blogger.com/_skGtCbVaJ2o/RgCYE__cfkI/AAAAAAAAAAo/EDcokPAlKMg/s1600-h/Stored+Procedure+Error.PNG"&gt;&lt;img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer;" src="http://bp1.blogger.com/_skGtCbVaJ2o/RgCYE__cfkI/AAAAAAAAAAo/EDcokPAlKMg/s320/Stored+Procedure+Error.PNG" alt="" id="BLOGGER_PHOTO_ID_5044198794319396418" border="0" /&gt;&lt;/a&gt;d procedure.&lt;p&gt;The strange thing is, every time, when I start the first debug  session in visual studio, it's fine, but when I tried the second, third time,  it's failing. &lt;/p&gt; &lt;p&gt;I have to restart the Visual studio 2005 Remote Debugger service manually  every time I want to step from the code into the stored procedure.&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp0.blogger.com/_skGtCbVaJ2o/RgCZtv_cfmI/AAAAAAAAAA4/LZv5BtoXdSM/s1600-h/Service.PNG"&gt;&lt;img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer;" src="http://bp0.blogger.com/_skGtCbVaJ2o/RgCZtv_cfmI/AAAAAAAAAA4/LZv5BtoXdSM/s320/Service.PNG" alt="" id="BLOGGER_PHOTO_ID_5044200593910693474" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp0.blogger.com/_skGtCbVaJ2o/RgCYUv_cflI/AAAAAAAAAAw/YN1c_HnksyQ/s1600-h/pesize.GIF"&gt;&lt;br /&gt;&lt;/a&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;a href="file:///C:/Documents%20and%20Settings/Jianwei%20Sun/Application%20Data/Windows%20Live%20Writer/PostSupportingFiles/877d0c2c-3e7e-4136-8455-ff3673eba90b/image%7B0%7D%5B9%5D.png" atomicselection="true"&gt;&lt;br /&gt;&lt;/a&gt; &lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7462882-7278230182561233467?l=gisresearch.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gisresearch.blogspot.com/feeds/7278230182561233467/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7462882&amp;postID=7278230182561233467' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7462882/posts/default/7278230182561233467'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7462882/posts/default/7278230182561233467'/><link rel='alternate' type='text/html' href='http://gisresearch.blogspot.com/2007/03/stored-procedure-debugging-error.html' title='Stored procedure debugging error.'/><author><name>J.W.</name><uri>http://www.blogger.com/profile/09241601264454722977</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://farm3.static.flickr.com/2116/1856041089_20ef060d43_o.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://bp1.blogger.com/_skGtCbVaJ2o/RgCYE__cfkI/AAAAAAAAAAo/EDcokPAlKMg/s72-c/Stored+Procedure+Error.PNG' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7462882.post-4307162855226908386</id><published>2007-03-01T22:22:00.001-05:00</published><updated>2007-04-08T10:28:11.515-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Asp.Net'/><title type='text'>Finished reading another book.</title><content type='html'>&lt;p&gt;I just finished reading another asp.net book &lt;strong&gt;&lt;a href="http://www.amazon.com/ASP-NET-Illustrated-Microsoft-NET-Development/dp/0321418344/sr=8-1/qid=1172802767/ref=pd_bbs_sr_1/103-9265823-4302222?ie=UTF8&amp;amp;s=books"&gt;ASP.NET 2.0 Illustrated&lt;/a&gt;. &lt;/strong&gt;This book is a very comprehensive coverage of Asp.net, but really didn't get into many details. It&amp;nbsp;gives a lot of screen captures, with a lot of MSDN style figures,&amp;nbsp;diagrams explaining different configuration settings. &amp;nbsp;I would use it more like a reference book.&amp;nbsp; It doesn't cover more updated features like ajax, which alone probably deserves another book.&lt;/p&gt; &lt;p&gt;If you are a beginner in asp.net, this is probably the book for you, but if you have known the asp.net very well, you probably will look for another advanced book.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7462882-4307162855226908386?l=gisresearch.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gisresearch.blogspot.com/feeds/4307162855226908386/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7462882&amp;postID=4307162855226908386' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7462882/posts/default/4307162855226908386'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7462882/posts/default/4307162855226908386'/><link rel='alternate' type='text/html' href='http://gisresearch.blogspot.com/2007/03/finished-reading-another-book.html' title='Finished reading another book.'/><author><name>J.W.</name><uri>http://www.blogger.com/profile/09241601264454722977</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://farm3.static.flickr.com/2116/1856041089_20ef060d43_o.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7462882.post-5221760495904752460</id><published>2007-02-28T21:27:00.001-05:00</published><updated>2007-04-08T10:28:19.779-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Asp.Net'/><title type='text'>The ASP.NET process identity does not have read permissions to the global assembly cache.</title><content type='html'>&lt;p&gt;I am trying to run the default website installed by the CLSA.net, but it keeps giving me this error until I reinstalled the asp.net on my development box.&lt;/p&gt; &lt;p&gt;The step I follow is :&lt;/p&gt; &lt;ol&gt; &lt;li&gt;Open a command prompt  &lt;li&gt;Stop IIS: iisreset /stop &lt;li&gt;Change to the .NET Framework 2.0 root directory: C:\winnt\Microsoft.Net\Framework\v2.0.50727\ &lt;li&gt;Reinstall&amp;nbsp;ASP.NET 2.0 by using the following command: aspnet_regiis -i command.  &lt;li&gt;Start IIS again after it has been run: iisreset /start&lt;/li&gt;&lt;/ol&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7462882-5221760495904752460?l=gisresearch.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gisresearch.blogspot.com/feeds/5221760495904752460/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7462882&amp;postID=5221760495904752460' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7462882/posts/default/5221760495904752460'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7462882/posts/default/5221760495904752460'/><link rel='alternate' type='text/html' href='http://gisresearch.blogspot.com/2007/02/aspnet-process-identity-does-not-have.html' title='The ASP.NET process identity does not have read permissions to the global assembly cache.'/><author><name>J.W.</name><uri>http://www.blogger.com/profile/09241601264454722977</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://farm3.static.flickr.com/2116/1856041089_20ef060d43_o.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7462882.post-5528074343216422652</id><published>2007-02-28T14:46:00.001-05:00</published><updated>2007-04-08T10:28:26.370-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='SQL'/><title type='text'>"Timeout expired" error message when the sql debugging is on.</title><content type='html'>&lt;p&gt;Following yesterday's post, now, I am able to debug into the stored procedure from my windows application or web application. But after a couple of times,&amp;nbsp;I start to receive annoying "Timeout expired" error message when the program tries to open a connection to the server.&lt;/p&gt; &lt;p&gt;Finally, I have to find another &lt;a href="http://support.microsoft.com/kb/830118/EN-US"&gt;KB830118&lt;/a&gt;,&amp;nbsp; and the status of this issue is "This behavior is by design".&amp;nbsp; I am start to doubt if "step into stored procedure" will cause the web site hanging in debug session, what is the real use of it. &lt;/p&gt; &lt;p&gt;Interesting..., maybe all those KBs are existing to address those stupid bugs.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7462882-5528074343216422652?l=gisresearch.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gisresearch.blogspot.com/feeds/5528074343216422652/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7462882&amp;postID=5528074343216422652' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7462882/posts/default/5528074343216422652'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7462882/posts/default/5528074343216422652'/><link rel='alternate' type='text/html' href='http://gisresearch.blogspot.com/2007/02/expired-error-message-when-sql.html' title='&amp;quot;Timeout expired&amp;quot; error message when the sql debugging is on.'/><author><name>J.W.</name><uri>http://www.blogger.com/profile/09241601264454722977</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://farm3.static.flickr.com/2116/1856041089_20ef060d43_o.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7462882.post-8429473016250396585</id><published>2007-02-27T20:56:00.001-05:00</published><updated>2007-02-27T20:56:07.369-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='SQL'/><title type='text'>Magic EXEC SP_SDIDEBUG 'legacy_on'</title><content type='html'>&lt;p&gt;In my previous job, I don't have to do too many stored procedures and those stored procedures are generally simple. The project I am working on right now involves a lot of stored procedures, and I need a good way to debug it. It's pretty easy if I am working in visual studio 2005 and SQL server 2005. Everything works right out of box. &lt;/p&gt; &lt;p&gt;But when I started to use visual studio 2003 to debug a stored procedure on SQL server 2005, it complained that the sp_sdidebug cannot be found. It's true, this particular debug procedure is not in the "Extended Stored Procedures" of the master database of the SQL server 2005, but it is in the master database of the SQL server 2000.&lt;/p&gt; &lt;p&gt;So, I moved the database to the SQL server 2000. It's getting much better, it can allow me to debug into the stored procedure from the server explorer.&amp;nbsp; It at least proved&amp;nbsp;that the SQL debugger is working.&amp;nbsp;But every time, when I tried to debug into the stored procedure from the vb.net code, it never stepped into the code.&lt;/p&gt; &lt;p&gt;I searched a lot of posts, and a lot of posts pointing to this &lt;a href="http://support.microsoft.com/kb/328151"&gt;KB328151&lt;/a&gt;. I tried this magic statement EXEC SP_SDIDEBUG 'legacy_on'&amp;nbsp; , no , it didn't work. I rebooted the server machine, tried this statement again, it seemed it worked finally.&amp;nbsp;&lt;/p&gt; &lt;p&gt;In the KB, it mentioned it's only an issue of SQL server sp3, actually, my SQL server is sp4 , and it still applys.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7462882-8429473016250396585?l=gisresearch.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gisresearch.blogspot.com/feeds/8429473016250396585/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7462882&amp;postID=8429473016250396585' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7462882/posts/default/8429473016250396585'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7462882/posts/default/8429473016250396585'/><link rel='alternate' type='text/html' href='http://gisresearch.blogspot.com/2007/02/magic-exec-spsdidebug.html' title='Magic EXEC SP_SDIDEBUG &amp;#39;legacy_on&amp;#39;'/><author><name>J.W.</name><uri>http://www.blogger.com/profile/09241601264454722977</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://farm3.static.flickr.com/2116/1856041089_20ef060d43_o.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7462882.post-900692534397081816</id><published>2007-02-26T07:45:00.001-05:00</published><updated>2007-02-26T07:45:34.167-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Programming'/><category scheme='http://www.blogger.com/atom/ns#' term='.Net'/><title type='text'>Visual studio 2005 Class Designer</title><content type='html'>&lt;p&gt;I am not a big fan of UML, or any diagram in the development process.&amp;nbsp; The biggest issue I found is the inconsistency between those nice diagrams and the actual codes.&amp;nbsp; I just found it's too difficult to think over every possible situations at the beginning stage of the project, not just the developers. The clients also have the same issue, they are not very clear what they want too at the beginning.&amp;nbsp;I find out unless you are a real guru in making those nice diagrams, and you can always make changes to those diagrams very fast ( I am NOT), it's so hard to keep those diagrams consistent with your code when the project requirements change. &lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;The visual studio class design is a different story. The changes you made to the designer can be applied to the code instantly, on the other hand, the changes you made to the code can be applied to the designer instantly too. You don't have to worry about two pieces any more, you can just worry about one piece. &lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;There is a &lt;a href="http://www.gotdotnet.com/workspaces/workspace.aspx?id=fe72608b-2b28-4cc1-9866-ea6f805f45f3"&gt;power toy&lt;/a&gt; for the enhancement here too.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7462882-900692534397081816?l=gisresearch.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gisresearch.blogspot.com/feeds/900692534397081816/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7462882&amp;postID=900692534397081816' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7462882/posts/default/900692534397081816'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7462882/posts/default/900692534397081816'/><link rel='alternate' type='text/html' href='http://gisresearch.blogspot.com/2007/02/visual-studio-2005-class-designer.html' title='Visual studio 2005 Class Designer'/><author><name>J.W.</name><uri>http://www.blogger.com/profile/09241601264454722977</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://farm3.static.flickr.com/2116/1856041089_20ef060d43_o.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7462882.post-620120960031768134</id><published>2007-02-22T22:35:00.000-05:00</published><updated>2007-02-22T22:38:41.913-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JavaScript'/><category scheme='http://www.blogger.com/atom/ns#' term='Asp.Net'/><title type='text'>Scrollable DataGrid with Sorting - ExtremeExperts</title><content type='html'>&lt;a href="http://www.extremeexperts.com/Net/Articles/ScrollableDataGridwithSorting.aspx"&gt;Scrollable DataGrid with Sorting - ExtremeExperts&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;I am working on a project which uses a lot of datagrid, and yes, it's still based on .Net 1.1 framework. The annoying issue is the scrolling, all the headers are scrolled with the grid when the datagrid is scrolled.  Asp.Net renders all the datagrid to one table, and it's not surprising that the header will be scrolled.&lt;br /&gt;&lt;br /&gt;I found a solution here, but the issue is the aligning of the columns between the header tables and the content tables rendered by the grid.&lt;br /&gt;&lt;br /&gt;I ends up writing some javascript code.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;function AdjustTable(firstTableId, secondTableId)&lt;br /&gt;{&lt;br /&gt;   if(document.getElementsByTagName)&lt;br /&gt;   {&lt;br /&gt;       var firstTable = document.getElementById(firstTableId);&lt;br /&gt;       var secondTable = document.getElementById(secondTableId);&lt;br /&gt;       if(firstTable!=null &amp;&amp;amp; secondTable!=null)&lt;br /&gt;       {&lt;br /&gt;           var firstTableRows = firstTable.getElementsByTagName("tr");                  &lt;br /&gt;           var secondTableRows=secondTable.getElementsByTagName("tr");&lt;br /&gt;           if(firstTableRows!=null &amp;&amp;amp; secondTableRows!=null)&lt;br /&gt;           {&lt;br /&gt;               if(firstTableRows.length&gt;0 &amp;&amp;amp; secondTableRows.length&gt;0)&lt;br /&gt;               {&lt;br /&gt;                   if(firstTableRows[0].cells.length==secondTableRows[0].cells.length)&lt;br /&gt;                   {&lt;br /&gt;                       for(i = 0; i &lt; secondTableRows[0].cells.length; i++)&lt;br /&gt;                       {&lt;br /&gt;                           secondTableRows[0].cells[i].style.width=firstTableRows[0].cells[i].clientWidth;&lt;br /&gt;                       }&lt;br /&gt;                   }&lt;br /&gt;               }&lt;br /&gt;           }&lt;br /&gt;       }//if(firstTable!=null &amp;&amp;amp; secondTable!=null)&lt;br /&gt;   }          &lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;This will loop through all the table cells in the first row for the second table, and set the width to be the same with the table cells in the first row of the first table.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7462882-620120960031768134?l=gisresearch.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gisresearch.blogspot.com/feeds/620120960031768134/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7462882&amp;postID=620120960031768134' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7462882/posts/default/620120960031768134'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7462882/posts/default/620120960031768134'/><link rel='alternate' type='text/html' href='http://gisresearch.blogspot.com/2007/02/scrollable-datagrid-with-sorting.html' title='Scrollable DataGrid with Sorting - ExtremeExperts'/><author><name>J.W.</name><uri>http://www.blogger.com/profile/09241601264454722977</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://farm3.static.flickr.com/2116/1856041089_20ef060d43_o.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7462882.post-406392999239072560</id><published>2007-02-20T22:47:00.001-05:00</published><updated>2007-02-22T22:39:47.354-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='SQL'/><title type='text'>SQL Server 2005 Compact Edition and SQL Server 2005 Express Edition</title><content type='html'>I have been using the Express Edition for a while, but are not aware the difference between the compact edition and the express edition. Here is a &lt;a href="http://www.microsoft.com/sql/editions/compact/sscecomparison.mspx"&gt;white paper&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7462882-406392999239072560?l=gisresearch.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gisresearch.blogspot.com/feeds/406392999239072560/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7462882&amp;postID=406392999239072560' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7462882/posts/default/406392999239072560'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7462882/posts/default/406392999239072560'/><link rel='alternate' type='text/html' href='http://gisresearch.blogspot.com/2007/02/sql-server-2005-compact-edition-and-sql.html' title='SQL Server 2005 Compact Edition and SQL Server 2005 Express Edition'/><author><name>J.W.</name><uri>http://www.blogger.com/profile/09241601264454722977</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://farm3.static.flickr.com/2116/1856041089_20ef060d43_o.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7462882.post-4289042521736739695</id><published>2007-02-12T14:02:00.001-05:00</published><updated>2007-02-22T22:40:12.645-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Asp.Net'/><title type='text'>Design time rendering and run time rendering.</title><content type='html'>&lt;p&gt;I was doing some work on the GMap.Control over the weekend. On thing I found is that whenever I drop the control on the form, it always gives me an error on rendering, error to create control, error to render a control.&lt;/p&gt; &lt;p&gt;The problem is , when the visual  studio render a control on the form, it will look for the DesignerAttribute, if it's not available, it will look for the default ControlDesigner. The ControlDesigner has a default method called GetDesignTimeHtml() , It will render the view on the form.&lt;/p&gt; &lt;p&gt;Use the reflector, here is what &lt;b&gt;GetDesignTimeHtml&lt;/b&gt;() will do by default:&lt;/p&gt; &lt;p&gt; &lt;/p&gt;&lt;pre&gt;public virtual &lt;a href="http://www.aisto.com/roeder/dotnet/Default.aspx?Object=1"&gt;string&lt;/a&gt; &lt;b&gt;GetDesignTimeHtml&lt;/b&gt;()&lt;br /&gt;{&lt;br /&gt;     &lt;a href="http://www.aisto.com/roeder/dotnet/Default.aspx?Object=2"&gt;StringWriter&lt;/a&gt; &lt;b&gt;writer1&lt;/b&gt; = new &lt;a href="http://www.aisto.com/roeder/dotnet/Default.aspx?Object=3"&gt;StringWriter&lt;/a&gt;(&lt;a href="http://www.aisto.com/roeder/dotnet/Default.aspx?Object=4"&gt;CultureInfo&lt;/a&gt;.&lt;a href="http://www.aisto.com/roeder/dotnet/Default.aspx?Object=5"&gt;InvariantCulture&lt;/a&gt;);&lt;br /&gt;     &lt;a href="http://www.aisto.com/roeder/dotnet/Default.aspx?Object=6"&gt;DesignTimeHtmlTextWriter&lt;/a&gt; &lt;b&gt;writer2&lt;/b&gt; = new &lt;a href="http://www.aisto.com/roeder/dotnet/Default.aspx?Object=7"&gt;DesignTimeHtmlTextWriter&lt;/a&gt;(&lt;a&gt;writer1&lt;/a&gt;);&lt;br /&gt;     &lt;a href="http://www.aisto.com/roeder/dotnet/Default.aspx?Object=8"&gt;string&lt;/a&gt; &lt;b&gt;text1&lt;/b&gt; = null;&lt;br /&gt;     &lt;a href="http://www.aisto.com/roeder/dotnet/Default.aspx?Object=9"&gt;bool&lt;/a&gt; &lt;b&gt;flag1&lt;/b&gt; = false;&lt;br /&gt;     &lt;a href="http://www.aisto.com/roeder/dotnet/Default.aspx?Object=10"&gt;bool&lt;/a&gt; &lt;b&gt;flag2&lt;/b&gt; = true;&lt;br /&gt;     &lt;a href="http://www.aisto.com/roeder/dotnet/Default.aspx?Object=11"&gt;Control&lt;/a&gt; &lt;b&gt;control1&lt;/b&gt; = null;&lt;br /&gt;     try&lt;br /&gt;     {&lt;br /&gt;           &lt;a&gt;control1&lt;/a&gt; = this.&lt;a href="http://www.aisto.com/roeder/dotnet/Default.aspx?Object=12"&gt;ViewControl&lt;/a&gt;;&lt;br /&gt;           &lt;a&gt;flag2&lt;/a&gt; = &lt;a&gt;control1&lt;/a&gt;.&lt;a href="http://www.aisto.com/roeder/dotnet/Default.aspx?Object=13"&gt;Visible&lt;/a&gt;;&lt;br /&gt;           if (!&lt;a&gt;flag2&lt;/a&gt;)&lt;br /&gt;           {&lt;br /&gt;                 &lt;a&gt;control1&lt;/a&gt;.&lt;a href="http://www.aisto.com/roeder/dotnet/Default.aspx?Object=14"&gt;Visible&lt;/a&gt; = true;&lt;br /&gt;                 &lt;a&gt;flag1&lt;/a&gt; = !this.&lt;a href="http://www.aisto.com/roeder/dotnet/Default.aspx?Object=15"&gt;UsePreviewControl&lt;/a&gt;;&lt;br /&gt;           }&lt;br /&gt;           &lt;a&gt;control1&lt;/a&gt;.&lt;a href="http://www.aisto.com/roeder/dotnet/Default.aspx?Object=16"&gt;RenderControl&lt;/a&gt;(&lt;a&gt;writer2&lt;/a&gt;);&lt;br /&gt;           &lt;a&gt;text1&lt;/a&gt; = &lt;a&gt;writer1&lt;/a&gt;.&lt;a href="http://www.aisto.com/roeder/dotnet/Default.aspx?Object=17"&gt;ToString&lt;/a&gt;();&lt;br /&gt;     }&lt;br /&gt;     catch (&lt;a href="http://www.aisto.com/roeder/dotnet/Default.aspx?Object=18"&gt;Exception&lt;/a&gt; &lt;b&gt;exception1&lt;/b&gt;)&lt;br /&gt;     {&lt;br /&gt;           &lt;a&gt;text1&lt;/a&gt; = this.&lt;a href="http://www.aisto.com/roeder/dotnet/Default.aspx?Object=19"&gt;GetErrorDesignTimeHtml&lt;/a&gt;(&lt;a&gt;exception1&lt;/a&gt;);&lt;br /&gt;     }&lt;br /&gt;     finally&lt;br /&gt;     {&lt;br /&gt;           if (&lt;a&gt;flag1&lt;/a&gt;)&lt;br /&gt;           {&lt;br /&gt;                 &lt;a&gt;control1&lt;/a&gt;.&lt;a href="http://www.aisto.com/roeder/dotnet/Default.aspx?Object=20"&gt;Visible&lt;/a&gt; = &lt;a&gt;flag2&lt;/a&gt;;&lt;br /&gt;           }&lt;br /&gt;     }&lt;br /&gt;     if ((&lt;a&gt;text1&lt;/a&gt; != null) &amp;amp;&amp; (&lt;a&gt;text1&lt;/a&gt;.&lt;a href="http://www.aisto.com/roeder/dotnet/Default.aspx?Object=21"&gt;Length&lt;/a&gt; != 0))&lt;br /&gt;     {&lt;br /&gt;           return &lt;a&gt;text1&lt;/a&gt;;&lt;br /&gt;     }&lt;br /&gt;     return this.&lt;a href="http://www.aisto.com/roeder/dotnet/Default.aspx?Object=22"&gt;GetEmptyDesignTimeHtml&lt;/a&gt;();&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;pre&gt;Actaully, at the design time, a lot of objects are not initialized properly, so it will cause an exception.&lt;/pre&gt;&lt;pre&gt;So, I made an easy approach, I override the GetDesignTimeHtml() method to let it simply draw a string. Of course, there are a lot of more interesting stuff you can do here.&lt;/pre&gt;&lt;pre&gt; &lt;/pre&gt;&lt;br /&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;div class="wlWriterSmartContent" id="57F11A72-B0E5-49c7-9094-E3A15BD5B5E7:7ff18bd1-b1dc-4bfe-b9f4-574001e1bd24" contenteditable="false" style="margin: 0px; padding: 0px; display: inline; float: none;"&gt;&lt;pre style="background-color: White;"&gt;&lt;div&gt;&lt;!--  Code highlighting produced by Actipro CodeHighlighter (freeware) http://www.CodeHighlighter.com/  --&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;        &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;public&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;override&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;string&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; GetDesignTimeHtml()&lt;br /&gt;       {&lt;br /&gt;           &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;try&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;br /&gt;           {&lt;br /&gt;               StringBuilder sb &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;=&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;new&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; System.Text.StringBuilder();&lt;br /&gt;               sb.Append(&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;"&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;GMap2 Server Control&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;"&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;);&lt;br /&gt;               &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;return&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; sb.ToString();&lt;br /&gt;           }&lt;br /&gt;           &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;catch&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; (Exception ex)&lt;br /&gt;           {&lt;br /&gt;               &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;return&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; GetErrorDesignTimeHtml(ex);&lt;br /&gt;           }&lt;br /&gt;       }&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt; &lt;/p&gt;&lt;br /&gt;&lt;p&gt;It at lease won't give me any error anymore.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7462882-4289042521736739695?l=gisresearch.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gisresearch.blogspot.com/feeds/4289042521736739695/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7462882&amp;postID=4289042521736739695' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7462882/posts/default/4289042521736739695'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7462882/posts/default/4289042521736739695'/><link rel='alternate' type='text/html' href='http://gisresearch.blogspot.com/2007/02/design-time-rendering-and-run-time.html' title='Design time rendering and run time rendering.'/><author><name>J.W.</name><uri>http://www.blogger.com/profile/09241601264454722977</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://farm3.static.flickr.com/2116/1856041089_20ef060d43_o.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7462882.post-7471521515466629443</id><published>2007-02-11T16:23:00.001-05:00</published><updated>2007-02-11T16:24:09.964-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='.Net'/><title type='text'>DataReader vs DataSet</title><content type='html'>A very good article about Data Access in .Net&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.theserverside.net/tt/articles/showarticle.tss?id=OptimizingADONET"&gt;Enterprise .NET Community: Designing Performance - Optimized ADO.NET Applications&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;This is also a question I was asked in an interview..&lt;br /&gt;&lt;h3&gt;Choosing Between a DataSet and a DataReader&lt;/h3&gt; &lt;p&gt;A critical choice when designing your application is whether to use a DataSet or a DataReader to retrieve data. If you need to retrieve many records rapidly, use a DataReader. The DataReader object is fast, returning a fire hose of read-only data from the server, one record at a time. In addition, retrieving results with a DataReader requires significantly less memory than a creating a DataSet. The DataReader does not allow random fetching, nor does it allow for updating the data. However, .NET data providers optimize their DataReaders for efficiently fetching large amounts of data.&lt;/p&gt; &lt;p&gt;In contrast, the DataSet object is a cache of disconnected data stored in memory on the client. In effect, it is a small database in itself. Because the DataSet contains all of the data that has been retrieved, you have more options in the way you can process the data. You can randomly choose records from within the DataSet and update/insert/delete records at will. You can also manipulate relational data as XML. This flexibility provides impressive functionality for any application, but comes with a high cost in memory consumption. In addition to keeping the entire result set in memory, the DataSet maintains both the original and the changed data, which leads to even higher memory usage. Do not use DataSets with very large result sets as the scalability of the application will be drastically reduced. &lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7462882-7471521515466629443?l=gisresearch.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gisresearch.blogspot.com/feeds/7471521515466629443/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7462882&amp;postID=7471521515466629443' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7462882/posts/default/7471521515466629443'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7462882/posts/default/7471521515466629443'/><link rel='alternate' type='text/html' href='http://gisresearch.blogspot.com/2007/02/datareader-vs-dataset.html' title='DataReader vs DataSet'/><author><name>J.W.</name><uri>http://www.blogger.com/profile/09241601264454722977</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://farm3.static.flickr.com/2116/1856041089_20ef060d43_o.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7462882.post-5300746981086428774</id><published>2007-02-02T21:19:00.001-05:00</published><updated>2007-02-02T21:19:57.266-05:00</updated><title type='text'>Good way to transfer database.</title><content type='html'>&lt;p&gt;I have been looking for a method which can easily transfer my database on the local machine to the hosting server.&amp;nbsp;I don't have the enterprise manager, the express management studio seems not support this functionality. I have been trying to write some scripts using smo, but was not very successful. Finally, I found this &lt;a href="http://www.codeplex.com/sqlhost/Wiki/View.aspx?title=Database%20Publishing%20Wizard"&gt;SQL Server Hosting Toolkit&lt;/a&gt;, and it's very useful. &lt;/p&gt; &lt;p&gt;1&amp;gt; Connect to your local database, and script the database into an SQL file.&lt;/p&gt; &lt;p&gt;2&amp;gt; Connect to the remote database, and open and SQL query window, then copy all the scripts into the SQL query window. Run the scripts, it will generate all the objects and data into the remote database.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7462882-5300746981086428774?l=gisresearch.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gisresearch.blogspot.com/feeds/5300746981086428774/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7462882&amp;postID=5300746981086428774' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7462882/posts/default/5300746981086428774'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7462882/posts/default/5300746981086428774'/><link rel='alternate' type='text/html' href='http://gisresearch.blogspot.com/2007/02/good-way-to-transfer-database.html' title='Good way to transfer database.'/><author><name>J.W.</name><uri>http://www.blogger.com/profile/09241601264454722977</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://farm3.static.flickr.com/2116/1856041089_20ef060d43_o.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7462882.post-5861773074161435060</id><published>2007-01-31T21:12:00.001-05:00</published><updated>2007-01-31T21:14:55.416-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='.Net'/><title type='text'>My first MsBuild task.</title><content type='html'>&lt;p&gt;I frequently used MsBuild in my build scripts, but really didn't have a chance to actually write a task myself. &lt;/p&gt; &lt;p&gt;One particular task I face is to publish the files in a directory to the FTP server. So, I googled, and tried to find a solution for this. The first hit I got back is &lt;a title="http://msbuildtasks.tigris.org/" href="http://msbuildtasks.tigris.org/"&gt;http://msbuildtasks.tigris.org/&lt;/a&gt;, which is a great community project. It includes a lot useful MsBuild tasks, include a FTP task. But what I wanted to FTP is a whole directory,  not just single website. So, I started to write a task called FtpDirectoy, which will loop through all the qualified files, and ftp them onto the server.&lt;/p&gt; &lt;p&gt;The task is not difficult to write, basically,  a new class has to be inherited from Microsoft.Build.Utilities.Task, then you set up a bunch of properties, finally, you have to override public override bool Execute(), and that will actually do the task.&lt;/p&gt; &lt;p&gt;The deployment is quite tricky, I copied the file at C:\Program Files\MSBuild\MSBuildCommunityTasks, and created a target file "CrystalGis.MsBuild.Tasks.Targets", which will then be included by the other project file.&lt;/p&gt; &lt;p&gt;Here the frustration comes, no matter what I do, the build task always told me that it couldn't find the task. Finally, I found an answer at &lt;a title="http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=122927&amp;SiteID=1" href="http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=122927&amp;amp;SiteID=1"&gt;http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=122927&amp;SiteID=1&lt;/a&gt;&lt;/p&gt; &lt;p&gt; &lt;/p&gt; &lt;p&gt;[&lt;b&gt;Keith Hill&lt;/b&gt;:Try adding the full path to the project file to the SafeImports reg key in the registry.  The location of the regkey is:&lt;br /&gt;HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\VisualStudio\8.0\MSBuild\SafeImports&lt;br /&gt;I saw this problem just the other day and this fixed it.  A better way to do this is to put your &amp;lt;UsingTask ...&amp;gt; in some &amp;lt;pick_a_name&amp;gt;.targets file and drop this targets file into a location that you can &amp;lt;Import ...&amp;gt; into your project file.  Then put the full path to the targets file into the SafeImports section of the registry.  This way, you only have to add the targets file once.  The other way you would have to add each project file you use it in to SafeImports, well at least the ones you load into VS 2005. ]&lt;/p&gt; &lt;p&gt;After I added that entry,everything flies.&lt;/p&gt; &lt;p&gt; &lt;/p&gt; &lt;div class="wlWriterSmartContent" id="57F11A72-B0E5-49c7-9094-E3A15BD5B5E7:013df76f-3f41-4b82-a4b0-907c679c1a09" contenteditable="false" style="margin: 0px; padding: 0px; display: inline; float: none;"&gt;&lt;pre style="background-color: White;"&gt;&lt;div&gt;&lt;!--  Code highlighting produced by Actipro CodeHighlighter (freeware) http://www.CodeHighlighter.com/  --&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;   &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;public&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;class&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; FtpDirectoy:Task&lt;br /&gt;   {&lt;br /&gt;       &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;#region&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; Constructor&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;br /&gt;&lt;br /&gt;       &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;public&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; FtpDirectoy()&lt;br /&gt;       {&lt;br /&gt;&lt;br /&gt;       }&lt;br /&gt;&lt;br /&gt;       &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;#endregion&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;       &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;#region&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; Input Parameters&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;br /&gt;&lt;br /&gt;       &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;private&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;string&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; _ftpAddrerss;&lt;br /&gt;&lt;br /&gt;       &lt;/span&gt;&lt;span style="color: rgb(128, 128, 128);"&gt;///&lt;/span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(128, 128, 128);"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;&lt;br /&gt;       &lt;/span&gt;&lt;span style="color: rgb(128, 128, 128);"&gt;///&lt;/span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt; Gets or sets the FTP addrerss.&lt;br /&gt;       &lt;/span&gt;&lt;span style="color: rgb(128, 128, 128);"&gt;///&lt;/span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(128, 128, 128);"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;&lt;br /&gt;       &lt;/span&gt;&lt;span style="color: rgb(128, 128, 128);"&gt;///&lt;/span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(128, 128, 128);"&gt;&amp;lt;value&amp;gt;&lt;/span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;The FTP addrerss.&lt;/span&gt;&lt;span style="color: rgb(128, 128, 128);"&gt;&amp;lt;/value&amp;gt;&lt;/span&gt;&lt;span style="color: rgb(128, 128, 128);"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;        &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;public&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;string&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; FtpAddrerss&lt;br /&gt;       {&lt;br /&gt;           &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;get&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; { &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;return&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; _ftpAddrerss; }&lt;br /&gt;           &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;set&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; { _ftpAddrerss &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;=&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; value; }&lt;br /&gt;       }&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;       &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;private&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;string&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; _username;&lt;br /&gt;&lt;br /&gt;       &lt;/span&gt;&lt;span style="color: rgb(128, 128, 128);"&gt;///&lt;/span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(128, 128, 128);"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;&lt;br /&gt;       &lt;/span&gt;&lt;span style="color: rgb(128, 128, 128);"&gt;///&lt;/span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt; Gets or sets the username.&lt;br /&gt;       &lt;/span&gt;&lt;span style="color: rgb(128, 128, 128);"&gt;///&lt;/span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(128, 128, 128);"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;&lt;br /&gt;       &lt;/span&gt;&lt;span style="color: rgb(128, 128, 128);"&gt;///&lt;/span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(128, 128, 128);"&gt;&amp;lt;value&amp;gt;&lt;/span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;The username.&lt;/span&gt;&lt;span style="color: rgb(128, 128, 128);"&gt;&amp;lt;/value&amp;gt;&lt;/span&gt;&lt;span style="color: rgb(128, 128, 128);"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;        &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;public&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;string&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; Username&lt;br /&gt;       {&lt;br /&gt;           &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;get&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; { &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;return&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; _username; }&lt;br /&gt;           &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;set&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; { _username &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;=&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; value; }&lt;br /&gt;       }&lt;br /&gt;&lt;br /&gt;       &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;private&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;string&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; _password;&lt;br /&gt;&lt;br /&gt;       &lt;/span&gt;&lt;span style="color: rgb(128, 128, 128);"&gt;///&lt;/span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(128, 128, 128);"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;&lt;br /&gt;       &lt;/span&gt;&lt;span style="color: rgb(128, 128, 128);"&gt;///&lt;/span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt; Gets or sets the password.&lt;br /&gt;       &lt;/span&gt;&lt;span style="color: rgb(128, 128, 128);"&gt;///&lt;/span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(128, 128, 128);"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;&lt;br /&gt;       &lt;/span&gt;&lt;span style="color: rgb(128, 128, 128);"&gt;///&lt;/span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(128, 128, 128);"&gt;&amp;lt;value&amp;gt;&lt;/span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;The password.&lt;/span&gt;&lt;span style="color: rgb(128, 128, 128);"&gt;&amp;lt;/value&amp;gt;&lt;/span&gt;&lt;span style="color: rgb(128, 128, 128);"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;        &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;public&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;string&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; Password&lt;br /&gt;       {&lt;br /&gt;           &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;get&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; { &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;return&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; _password; }&lt;br /&gt;           &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;set&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; { _password &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;=&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; value; }&lt;br /&gt;       }&lt;br /&gt;&lt;br /&gt;       &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;private&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;bool&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; _usePassive;&lt;br /&gt;&lt;br /&gt;       &lt;/span&gt;&lt;span style="color: rgb(128, 128, 128);"&gt;///&lt;/span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(128, 128, 128);"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;&lt;br /&gt;       &lt;/span&gt;&lt;span style="color: rgb(128, 128, 128);"&gt;///&lt;/span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt; Gets or sets the behavior of a client application's data transfer process.&lt;br /&gt;       &lt;/span&gt;&lt;span style="color: rgb(128, 128, 128);"&gt;///&lt;/span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(128, 128, 128);"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;&lt;br /&gt;       &lt;/span&gt;&lt;span style="color: rgb(128, 128, 128);"&gt;///&lt;/span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(128, 128, 128);"&gt;&amp;lt;value&amp;gt;&amp;lt;c&amp;gt;&lt;/span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;true&lt;/span&gt;&lt;span style="color: rgb(128, 128, 128);"&gt;&amp;lt;/c&amp;gt;&lt;/span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt; if [use passive]; otherwise, &lt;/span&gt;&lt;span style="color: rgb(128, 128, 128);"&gt;&amp;lt;c&amp;gt;&lt;/span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;false&lt;/span&gt;&lt;span style="color: rgb(128, 128, 128);"&gt;&amp;lt;/c&amp;gt;&lt;/span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;.&lt;/span&gt;&lt;span style="color: rgb(128, 128, 128);"&gt;&amp;lt;/value&amp;gt;&lt;/span&gt;&lt;span style="color: rgb(128, 128, 128);"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;        &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;public&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;bool&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; UsePassive&lt;br /&gt;       {&lt;br /&gt;           &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;get&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; { &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;return&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; _usePassive; }&lt;br /&gt;           &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;set&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; { _usePassive &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;=&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; value; }&lt;br /&gt;       }&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;       &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;private&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; ITaskItem[] _files;&lt;br /&gt;&lt;br /&gt;       &lt;/span&gt;&lt;span style="color: rgb(128, 128, 128);"&gt;///&lt;/span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(128, 128, 128);"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;&lt;br /&gt;       &lt;/span&gt;&lt;span style="color: rgb(128, 128, 128);"&gt;///&lt;/span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt; Gets or sets the files to zip.&lt;br /&gt;       &lt;/span&gt;&lt;span style="color: rgb(128, 128, 128);"&gt;///&lt;/span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(128, 128, 128);"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;&lt;br /&gt;       &lt;/span&gt;&lt;span style="color: rgb(128, 128, 128);"&gt;///&lt;/span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(128, 128, 128);"&gt;&amp;lt;value&amp;gt;&lt;/span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;The files to zip.&lt;/span&gt;&lt;span style="color: rgb(128, 128, 128);"&gt;&amp;lt;/value&amp;gt;&lt;/span&gt;&lt;span style="color: rgb(128, 128, 128);"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;        [Required]&lt;br /&gt;       &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;public&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; ITaskItem[] Files&lt;br /&gt;       {&lt;br /&gt;           &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;get&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; { &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;return&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; _files; }&lt;br /&gt;           &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;set&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; { _files &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;=&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; value; }&lt;br /&gt;       }&lt;br /&gt;&lt;br /&gt;       &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;private&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;string&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; _workingDirectory;&lt;br /&gt;&lt;br /&gt;       &lt;/span&gt;&lt;span style="color: rgb(128, 128, 128);"&gt;///&lt;/span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(128, 128, 128);"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;&lt;br /&gt;       &lt;/span&gt;&lt;span style="color: rgb(128, 128, 128);"&gt;///&lt;/span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt; Gets or sets the working directory for the zip file.&lt;br /&gt;       &lt;/span&gt;&lt;span style="color: rgb(128, 128, 128);"&gt;///&lt;/span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(128, 128, 128);"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;&lt;br /&gt;       &lt;/span&gt;&lt;span style="color: rgb(128, 128, 128);"&gt;///&lt;/span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(128, 128, 128);"&gt;&amp;lt;value&amp;gt;&lt;/span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;The working directory.&lt;/span&gt;&lt;span style="color: rgb(128, 128, 128);"&gt;&amp;lt;/value&amp;gt;&lt;/span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;&lt;br /&gt;       &lt;/span&gt;&lt;span style="color: rgb(128, 128, 128);"&gt;///&lt;/span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(128, 128, 128);"&gt;&amp;lt;remarks&amp;gt;&lt;/span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;&lt;br /&gt;       &lt;/span&gt;&lt;span style="color: rgb(128, 128, 128);"&gt;///&lt;/span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt; The working directory is the base of the zip file. &lt;br /&gt;       &lt;/span&gt;&lt;span style="color: rgb(128, 128, 128);"&gt;///&lt;/span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt; All files will be made relative from the working directory.&lt;br /&gt;       &lt;/span&gt;&lt;span style="color: rgb(128, 128, 128);"&gt;///&lt;/span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(128, 128, 128);"&gt;&amp;lt;/remarks&amp;gt;&lt;/span&gt;&lt;span style="color: rgb(128, 128, 128);"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;        &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;public&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;string&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; WorkingDirectory&lt;br /&gt;       {&lt;br /&gt;           &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;get&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; { &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;return&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; _workingDirectory; }&lt;br /&gt;           &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;set&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; { _workingDirectory &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;=&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; value; }&lt;br /&gt;       }&lt;br /&gt;&lt;br /&gt;       &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;#endregion&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;       &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;#region&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; Task Overrides&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;br /&gt;&lt;br /&gt;       &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;public&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;override&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;bool&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; Execute()&lt;br /&gt;       {&lt;br /&gt;           Log.LogMessage(CrystalGis.MsBuild.Tasks.Properties.Resources.FtpDirectory, _workingDirectory);&lt;br /&gt;           &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;foreach&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; (ITaskItem fileItem &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;in&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; _files)&lt;br /&gt;           {&lt;br /&gt;               &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;string&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; name &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;=&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; fileItem.ItemSpec;&lt;br /&gt;               &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;if&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; (&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;!&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;File.Exists(name))&lt;br /&gt;               {&lt;br /&gt;                   &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;continue&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;;&lt;br /&gt;               }&lt;br /&gt;               &lt;/span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;//&lt;/span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;Ftp file here.......&lt;/span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;                &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;string&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; remoteUrl&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;=&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;GetUriFromRemoteName(name);&lt;br /&gt;               &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;if&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; (&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;string&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;.IsNullOrEmpty(remoteUrl))&lt;br /&gt;                   &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;continue&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;;&lt;br /&gt;               FtpFile(name, remoteUrl );&lt;br /&gt;           }&lt;br /&gt;           &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;return&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;true&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;;&lt;br /&gt;       }&lt;br /&gt;&lt;br /&gt;       &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;#endregion&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; Task Overrides&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;br /&gt;&lt;br /&gt;       &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;#region&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; Private &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;br /&gt;&lt;br /&gt;       &lt;/span&gt;&lt;span style="color: rgb(128, 128, 128);"&gt;///&lt;/span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(128, 128, 128);"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;&lt;br /&gt;       &lt;/span&gt;&lt;span style="color: rgb(128, 128, 128);"&gt;///&lt;/span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt; Gets the name of the URI from remote.&lt;br /&gt;       &lt;/span&gt;&lt;span style="color: rgb(128, 128, 128);"&gt;///&lt;/span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(128, 128, 128);"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;&lt;br /&gt;       &lt;/span&gt;&lt;span style="color: rgb(128, 128, 128);"&gt;///&lt;/span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(128, 128, 128);"&gt;&amp;lt;param name="fileNameWithPath"&amp;gt;&lt;/span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;The file name with path.&lt;/span&gt;&lt;span style="color: rgb(128, 128, 128);"&gt;&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;&lt;br /&gt;       &lt;/span&gt;&lt;span style="color: rgb(128, 128, 128);"&gt;///&lt;/span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(128, 128, 128);"&gt;&amp;lt;returns&amp;gt;&amp;lt;/returns&amp;gt;&lt;/span&gt;&lt;span style="color: rgb(128, 128, 128);"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;        &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;private&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;string&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; GetUriFromRemoteName(&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;string&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; fileNameWithPath)&lt;br /&gt;       {&lt;br /&gt;           &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;string&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; pathWithoutWorkingDirectory;&lt;br /&gt;           Log.LogMessage(Properties.Resources.GetUriForFile, fileNameWithPath);&lt;br /&gt;           &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;int&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; index &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;=&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; fileNameWithPath.IndexOf(_workingDirectory);&lt;br /&gt;           &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;if&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; (index &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;-&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;1&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;)&lt;br /&gt;           {&lt;br /&gt;               pathWithoutWorkingDirectory &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;=&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; fileNameWithPath.Substring(index&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;+&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;_workingDirectory.Length&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;+&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;1&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;);&lt;br /&gt;               &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;return&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; _ftpAddrerss &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;+&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;"&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;/&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;"&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;+&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; pathWithoutWorkingDirectory.Replace(&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;"&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;\\&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;"&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;,&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;"&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;/&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;"&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;);&lt;br /&gt;           }&lt;br /&gt;           &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;else&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;br /&gt;           {&lt;br /&gt;               Log.LogError(Properties.Resources.FtpFileInvalid, fileNameWithPath);&lt;br /&gt;               &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;return&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;string&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;.Empty;&lt;br /&gt;           }&lt;br /&gt;       }&lt;br /&gt;&lt;br /&gt;       &lt;/span&gt;&lt;span style="color: rgb(128, 128, 128);"&gt;///&lt;/span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(128, 128, 128);"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;&lt;br /&gt;       &lt;/span&gt;&lt;span style="color: rgb(128, 128, 128);"&gt;///&lt;/span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt; FTPs the file.&lt;br /&gt;       &lt;/span&gt;&lt;span style="color: rgb(128, 128, 128);"&gt;///&lt;/span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(128, 128, 128);"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;&lt;br /&gt;       &lt;/span&gt;&lt;span style="color: rgb(128, 128, 128);"&gt;///&lt;/span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(128, 128, 128);"&gt;&amp;lt;param name="localFile"&amp;gt;&lt;/span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;The local file.&lt;/span&gt;&lt;span style="color: rgb(128, 128, 128);"&gt;&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;&lt;br /&gt;       &lt;/span&gt;&lt;span style="color: rgb(128, 128, 128);"&gt;///&lt;/span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(128, 128, 128);"&gt;&amp;lt;param name="remoteUri"&amp;gt;&lt;/span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;The remote URI.&lt;/span&gt;&lt;span style="color: rgb(128, 128, 128);"&gt;&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;span style="color: rgb(128, 128, 128);"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;        &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;private&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;bool&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; FtpFile(&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;string&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; localFile, &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;string&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; remoteUri)&lt;br /&gt;       {&lt;br /&gt;           Log.LogMessage(Properties.Resources.FtpUploading, localFile, remoteUri);&lt;br /&gt;           Uri ftpUri;&lt;br /&gt;           &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;if&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; (&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;!&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;Uri.TryCreate(remoteUri, UriKind.Absolute, &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;out&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; ftpUri))&lt;br /&gt;           {&lt;br /&gt;               Log.LogError(Properties.Resources.FtpUriInvalid, remoteUri);&lt;br /&gt;               &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;return&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;false&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;;&lt;br /&gt;           }&lt;br /&gt;&lt;br /&gt;           FtpWebRequest request &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;=&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; (FtpWebRequest)WebRequest.Create(ftpUri);&lt;br /&gt;           request.Method &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;=&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; WebRequestMethods.Ftp.UploadFile;&lt;br /&gt;           request.UseBinary &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;=&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;true&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;;&lt;br /&gt;           request.ContentLength &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;=&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; localFile.Length;&lt;br /&gt;           request.UsePassive &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;=&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; _usePassive;&lt;br /&gt;           &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;if&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; (&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;!&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;string&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;.IsNullOrEmpty(_username))&lt;br /&gt;               request.Credentials &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;=&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;new&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; NetworkCredential(_username, _password);&lt;br /&gt;&lt;br /&gt;           &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;const&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;int&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; bufferLength &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;=&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;2048&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;;&lt;br /&gt;           &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;byte&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;[] buffer &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;=&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;new&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;byte&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;[bufferLength];&lt;br /&gt;           &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;int&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; readBytes &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;=&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;0&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;;&lt;br /&gt;           &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;long&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; totalBytes &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;=&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; localFile.Length;&lt;br /&gt;           &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;long&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; progressUpdated &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;=&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;0&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;;&lt;br /&gt;           &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;long&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; wroteBytes &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;=&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;0&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;;&lt;br /&gt;           FileInfo localFileInfo &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;=&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;new&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; FileInfo(localFile);&lt;br /&gt;           &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;try&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;br /&gt;           {&lt;br /&gt;               Stopwatch watch &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;=&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; Stopwatch.StartNew();&lt;br /&gt;               &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;using&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; (Stream fileStream &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;=&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; localFileInfo.OpenRead(),&lt;br /&gt;                           requestStream &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;=&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; request.GetRequestStream())&lt;br /&gt;               {&lt;br /&gt;                   &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;do&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;br /&gt;                   {&lt;br /&gt;                       readBytes &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;=&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; fileStream.Read(buffer, &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;0&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;, bufferLength);&lt;br /&gt;                       requestStream.Write(buffer, &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;0&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;, readBytes);&lt;br /&gt;                       wroteBytes &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;+=&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; readBytes;&lt;br /&gt;&lt;br /&gt;                       &lt;/span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;//&lt;/span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt; log progress every 5 seconds&lt;/span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;                        &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;if&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; (watch.ElapsedMilliseconds &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;-&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; progressUpdated &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;5000&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;)&lt;br /&gt;                       {&lt;br /&gt;                           progressUpdated &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;=&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; watch.ElapsedMilliseconds;&lt;br /&gt;                           Log.LogMessage(MessageImportance.Low,&lt;br /&gt;                               Properties.Resources.FtpPercentComplete,&lt;br /&gt;                               wroteBytes &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;*&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;100&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;/&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; totalBytes,&lt;br /&gt;                               FormatBytesPerSecond(wroteBytes, watch.Elapsed.TotalSeconds, &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;1&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;));&lt;br /&gt;                       }&lt;br /&gt;                   }&lt;br /&gt;                   &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;while&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; (readBytes &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;!=&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;0&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;);&lt;br /&gt;               }&lt;br /&gt;               watch.Stop();&lt;br /&gt;&lt;br /&gt;               &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;using&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; (FtpWebResponse response &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;=&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; (FtpWebResponse)request.GetResponse())&lt;br /&gt;               {&lt;br /&gt;                   Log.LogMessage(MessageImportance.Low, Properties.Resources.FtpUploadComplete, response.StatusDescription);&lt;br /&gt;                   Log.LogMessage(Properties.Resources.FtpTransfered,&lt;br /&gt;                       FormatByte(totalBytes, &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;1&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;),&lt;br /&gt;                       FormatBytesPerSecond(totalBytes, watch.Elapsed.TotalSeconds, &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;1&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;),&lt;br /&gt;                       watch.Elapsed.ToString());&lt;br /&gt;                   response.Close();&lt;br /&gt;               }&lt;br /&gt;           }&lt;br /&gt;           &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;catch&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; (Exception ex)&lt;br /&gt;           {&lt;br /&gt;               Log.LogErrorFromException(ex);&lt;br /&gt;               &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;return&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;false&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;;&lt;br /&gt;           }&lt;br /&gt;&lt;br /&gt;           &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;return&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;true&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;;&lt;br /&gt;       }&lt;br /&gt;&lt;br /&gt;&lt;br /&gt; &lt;br /&gt;       &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;#endregion&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;br /&gt;   }&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7462882-5861773074161435060?l=gisresearch.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gisresearch.blogspot.com/feeds/5861773074161435060/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7462882&amp;postID=5861773074161435060' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7462882/posts/default/5861773074161435060'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7462882/posts/default/5861773074161435060'/><link rel='alternate' type='text/html' href='http://gisresearch.blogspot.com/2007/01/my-first-msbuild-task.html' title='My first MsBuild task.'/><author><name>J.W.</name><uri>http://www.blogger.com/profile/09241601264454722977</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://farm3.static.flickr.com/2116/1856041089_20ef060d43_o.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7462882.post-5995459935167123134</id><published>2007-01-29T22:22:00.001-05:00</published><updated>2007-04-11T22:48:22.672-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Life'/><title type='text'>I finally decided to move on the new position.</title><content type='html'>&lt;p&gt;The&amp;nbsp;five and a half&amp;nbsp;years experiences at DDTI are invaluable. I really have a lot of passion to devoted into my work at my first three years. I could stay overnight to fix a memory leak. I could try to improve a product even I am not assigned to do that.&lt;/p&gt; &lt;p&gt;I liked the people I work with, and apparently, they liked me too. &lt;/p&gt; &lt;p&gt;Yes, I am frustrated by some minor issues. I am not sure why I am not paid at a fair market value. I don't expect to be paid more&amp;nbsp;than others because I don't think myself smarter than others. I tried NOT to take any of those attitudes to my work because I understand what is considered professional.&lt;/p&gt; &lt;p&gt;The surprising thing is that they did make an counter offer to try to let me stay. I am really surprised at how much I am&amp;nbsp;actually appreciated at the final days of my work. They want to increase my salary more than what I have been increased in all five and a half years. I just don't feel comfortable to take this counter offer. &lt;/p&gt; &lt;p&gt;I think I am a loser in this process too. I have this value in the company, but can only have them pay me that value when I decided to leave. &lt;/p&gt; &lt;p&gt;I decided to move on, and I hope I can restore my passion to the software development.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7462882-5995459935167123134?l=gisresearch.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gisresearch.blogspot.com/feeds/5995459935167123134/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7462882&amp;postID=5995459935167123134' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7462882/posts/default/5995459935167123134'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7462882/posts/default/5995459935167123134'/><link rel='alternate' type='text/html' href='http://gisresearch.blogspot.com/2007/01/i-finally-decided-to-move-on-new.html' title='I finally decided to move on the new position.'/><author><name>J.W.</name><uri>http://www.blogger.com/profile/09241601264454722977</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://farm3.static.flickr.com/2116/1856041089_20ef060d43_o.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7462882.post-7974448593591560246</id><published>2007-01-21T10:58:00.001-05:00</published><updated>2007-01-29T22:24:02.045-05:00</updated><title type='text'>Merged two blogs together..</title><content type='html'>&lt;p&gt;I am able to convert the old blogger account to the new blogger, and I merged the two accounts together. I didn't find an easy way to merge two blogger's, so I simply copy and paste the posts.&lt;/p&gt; &lt;p&gt;Those posts are not written today, they are just pasted today..&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7462882-7974448593591560246?l=gisresearch.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gisresearch.blogspot.com/feeds/7974448593591560246/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7462882&amp;postID=7974448593591560246' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7462882/posts/default/7974448593591560246'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7462882/posts/default/7974448593591560246'/><link rel='alternate' type='text/html' href='http://gisresearch.blogspot.com/2007/01/merged-two-blogs-together.html' title='Merged two blogs together..'/><author><name>J.W.</name><uri>http://www.blogger.com/profile/09241601264454722977</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://farm3.static.flickr.com/2116/1856041089_20ef060d43_o.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7462882.post-8606631982713226350</id><published>2007-01-21T10:35:00.000-05:00</published><updated>2007-01-21T10:41:50.438-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Programming'/><title type='text'>check in the test project in Google code.</title><content type='html'>Use some kind of source safe control is not only for backing up the source code, it can also show you the history of the project evolvement.&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: left;"&gt;I have heard  of the  &lt;a href="http://code.google.com/"&gt;Google code&lt;/a&gt; before, but never tried it before. It uses the subversion to do the source control, which I have tried to check out a couple of open source project from &lt;a href="http://subversion.tigris.org/"&gt;SVN&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;I have never tried to host my own project before. So, I want to give it a try.&lt;br /&gt;&lt;br /&gt;The tools I am using &lt;a href="http://tortoisesvn.tigris.org/"&gt;TortoiseSVN&lt;/a&gt;, which also has a sibling called TortoiseSVN. Both are very handy tools.&lt;br /&gt;&lt;br /&gt;Here are the steps I followed:&lt;br /&gt;&lt;br /&gt;1. Create a project on google code.&lt;br /&gt;2. Right Click the project folder , and select "Import " to check the source code into the google code repository. It will prompt for the url , use the http://**.**.**/trunck.&lt;br /&gt;3. After the codes were imported into to the server, I tried to make some changes to the code, but it gave me an error (MKCOL405) when I tried to make some changes and commit the changes.&lt;br /&gt;4. So, I deleted the original project, and tried to check out the project from the svn. It created a little folder (.svn) under the project folder. I believe it has all the information which the TortoiseSVN tool needed to communicate with the server.&lt;br /&gt;5. Now, it seems that I can make the changes, update the server, and compare the changes.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7462882-8606631982713226350?l=gisresearch.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gisresearch.blogspot.com/feeds/8606631982713226350/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7462882&amp;postID=8606631982713226350' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7462882/posts/default/8606631982713226350'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7462882/posts/default/8606631982713226350'/><link rel='alternate' type='text/html' href='http://gisresearch.blogspot.com/2007/01/check-in-test-project-in-google-code.html' title='check in the test project in Google code.'/><author><name>J.W.</name><uri>http://www.blogger.com/profile/09241601264454722977</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://farm3.static.flickr.com/2116/1856041089_20ef060d43_o.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7462882.post-2161295308717194132</id><published>2007-01-21T10:34:00.000-05:00</published><updated>2007-01-21T10:43:38.254-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Programming'/><title type='text'>Start to review some college stuff.</title><content type='html'>For some reason, I found in day-to-day work, I focused on too much RAD (Rapid Application Development) , and I lost some ability to write some simple data structure code.&lt;br /&gt;&lt;br /&gt;I guess many developers nowadays rely too much on libraries, without enough attention paid to how those libraries were actually develped.&lt;br /&gt;&lt;br /&gt;I think I need some time to review some basic codes like how to write some basic data structure and their operations.&lt;br /&gt;1. link list.&lt;br /&gt;2. stack.&lt;br /&gt;3. queue.&lt;br /&gt;4. tree.&lt;br /&gt;5. graph.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7462882-2161295308717194132?l=gisresearch.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gisresearch.blogspot.com/feeds/2161295308717194132/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7462882&amp;postID=2161295308717194132' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7462882/posts/default/2161295308717194132'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7462882/posts/default/2161295308717194132'/><link rel='alternate' type='text/html' href='http://gisresearch.blogspot.com/2007/01/start-to-review-some-college-stuff.html' title='Start to review some college stuff.'/><author><name>J.W.</name><uri>http://www.blogger.com/profile/09241601264454722977</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://farm3.static.flickr.com/2116/1856041089_20ef060d43_o.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7462882.post-3336727668387506296</id><published>2007-01-21T10:33:00.000-05:00</published><updated>2007-01-21T10:44:18.368-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Programming'/><category scheme='http://www.blogger.com/atom/ns#' term='.Net'/><title type='text'>What is managed resources.</title><content type='html'>There have been enough posts about IDispose in .Net. The basically idea, to deterministically free up a resource, you need to implement the IDispose interface, also, it's better to offer a finalize method too.&lt;br /&gt;&lt;br /&gt;Something like this:&lt;br /&gt;&lt;br /&gt;MyResource:IDispose&lt;br /&gt;{&lt;br /&gt;~MyResource()&lt;br /&gt;{&lt;br /&gt; Dispose(false);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public void Dispose()&lt;br /&gt;{&lt;br /&gt; Dispose(true);&lt;br /&gt; GC.SuppressFinalize(this);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;protected virtual void Dispose(bool disposing)&lt;br /&gt;&lt;code&gt;&lt;/code&gt;{&lt;br /&gt;     if(disposing)&lt;br /&gt;     {//clean up managed resources.&lt;br /&gt;     }&lt;br /&gt;     //clean up unmanaged resources.&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;So, my question is : &lt;span style="color: rgb(255, 0, 0);"&gt;what exactly is the unmanaged resources?&lt;/span&gt; &lt;br /&gt;&lt;br /&gt;Are GDI+ objectes considered unmanged resources ?  How about sockets, other windows resources ... ?&lt;br /&gt;&lt;br /&gt;&lt;a href="http://blogs.msdn.com/davidklinems/archive/2006/01/10/511315.aspx"&gt;David Kline has a good example&lt;/a&gt; here :&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;using System;&lt;br /&gt;using System.Diagnostics;&lt;br /&gt;using System.Runtime.InteropServices;&lt;br /&gt;&lt;br /&gt;namespace Snippet&lt;br /&gt;{&lt;br /&gt;///&lt;br /&gt;/// Wrapper for the Win32 Device Context (DC)&lt;br /&gt;///&lt;br /&gt;public class DeviceContext : IDisposable&lt;br /&gt;{&lt;br /&gt;// the Win32 Device Context (DC) object&lt;br /&gt;private IntPtr hDC;&lt;br /&gt;&lt;br /&gt;// window handle associated with the DC&lt;br /&gt;private IntPtr hWnd;&lt;br /&gt;&lt;br /&gt;///&lt;br /&gt;/// Constructor.&lt;br /&gt;///&lt;br /&gt;///&lt;br /&gt;/// The window handle for which to retrieve the device context&lt;br /&gt;///&lt;br /&gt;public DeviceContext(IntPtr hwnd)&lt;br /&gt;{&lt;br /&gt;// call the p/invoke to get the device context for the specified window handle&lt;br /&gt;IntPtr hdc = GetDC(hwnd);&lt;br /&gt;&lt;br /&gt;// verify that the GetDC call succeeded&lt;br /&gt;if(hdc == IntPtr.Zero)&lt;br /&gt;{&lt;br /&gt;throw new Exception("Failed to get the DeviceContext for the specified window handle");&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;// store the window handle and device context for future reference&lt;br /&gt;this.hWnd = hwnd;&lt;br /&gt;this.hDC = hdc;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;///&lt;br /&gt;/// Finalizer&lt;br /&gt;///&lt;br /&gt;~DeviceContext()&lt;br /&gt;{&lt;br /&gt;// dispose the object (unmanaged resources)&lt;br /&gt;this.Dispose(false);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;///&lt;br /&gt;/// Cleanup the object (implementation if IDisposable::Dispose)&lt;br /&gt;///&lt;br /&gt;public void Dispose()&lt;br /&gt;{&lt;br /&gt;// clean up our resources (managed and unmanaged resources)&lt;br /&gt;this.Dispose(true);&lt;br /&gt;&lt;br /&gt;// suppress finalization&lt;br /&gt;// the finalizer also calls our cleanup code&lt;br /&gt;// cleanup need only occur once&lt;br /&gt;GC.SuppressFinalize(this);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;///&lt;br /&gt;/// Cleanup resources used by the object&lt;br /&gt;///&lt;br /&gt;///&lt;br /&gt;/// Are we fully disposing the object?&lt;br /&gt;/// True will release all managed resources, unmanaged resources are always released&lt;br /&gt;///&lt;br /&gt;protected virtual void Dispose(Boolean disposing)&lt;br /&gt;{&lt;br /&gt;if(disposing)&lt;br /&gt;{&lt;br /&gt;//*** release any managed resources&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;// release unmanaged resources&lt;br /&gt;if(this.hDC == IntPtr.Zero)&lt;br /&gt;{&lt;br /&gt;// we're already been disposed, nothing left to do&lt;br /&gt;return;&lt;br /&gt;}&lt;br /&gt;Int32 ret = ReleaseDC(this.hWnd, this.hDC);&lt;br /&gt;this.hDC = IntPtr.Zero;&lt;br /&gt;this.hWnd = IntPtr.Zero;&lt;br /&gt;&lt;br /&gt;// assert if the DC was not released.&lt;br /&gt;Debug.Assert(ret != 0,&lt;br /&gt;"Failed to release DeviceContext.");&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;//*** add desired p/invoke definitions&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;Based on my experiences, most of the unmanaged resources have been already wrapped inside .Net class, and those are really should be treated like managed resources. For example, those objects defined in System.Drawing like &lt;a href="http://msdn2.microsoft.com/en-us/library/system.drawing.bitmap.aspx"&gt;bitmaps&lt;/a&gt;, &lt;a href="http://msdn2.microsoft.com/en-us/library/hcb9kaf8%28en-US,VS.80%29.aspx"&gt;fonts&lt;/a&gt;, &lt;a href="http://msdn2.microsoft.com/library/ms130065%28en-US,VS.80%29.aspx"&gt;meshes&lt;/a&gt; and &lt;a href="http://msdn2.microsoft.com/library/ms130423%28en-US,VS.80%29.aspx"&gt;textures&lt;/a&gt;, they are managed objects containing reference to unmanged resources.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7462882-3336727668387506296?l=gisresearch.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gisresearch.blogspot.com/feeds/3336727668387506296/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7462882&amp;postID=3336727668387506296' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7462882/posts/default/3336727668387506296'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7462882/posts/default/3336727668387506296'/><link rel='alternate' type='text/html' href='http://gisresearch.blogspot.com/2007/01/what-is-managed-resources.html' title='What is managed resources.'/><author><name>J.W.</name><uri>http://www.blogger.com/profile/09241601264454722977</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://farm3.static.flickr.com/2116/1856041089_20ef060d43_o.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7462882.post-872615860962701962</id><published>2007-01-21T10:32:00.000-05:00</published><updated>2007-01-21T10:44:44.281-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Programming'/><title type='text'>I have a windows service program which depends a sql database. Sometimes, when the machine starts and my program tries to connect the database, the da</title><content type='html'>I have a windows service program which depends a sql database. Sometimes, when the machine starts and my program tries to connect the database, the database is not fully initialized yet, so it will throw an error in the startup procedure, and the service won't start.&lt;br /&gt;&lt;br /&gt;I tried to a couple of solutions :&lt;br /&gt;&lt;br /&gt;1&gt; The first one I tried to is to set the recovery options of the service property, set it to restart the service if it fails. I actually misunderstand this property until I got an reply from a msdn newsgroup:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;span&gt;&gt;&lt;/span&gt;&lt;br /&gt;&lt;span&gt;&gt;&gt; &lt;/span&gt;Recover options are only relevant if your service executable crashes, not&lt;br /&gt;&lt;span&gt;&gt;&gt; &lt;/span&gt;because of any HRESULTs which might lead to ending a process. If a&lt;br /&gt;&lt;span&gt;&gt;&gt; &lt;/span&gt;process is just ending by leaving all thread functions that is pretty OK&lt;br /&gt;&lt;span&gt;&gt;&gt; &lt;/span&gt;for the service control manager.&lt;br /&gt;&lt;span&gt;&gt;&gt;&lt;/span&gt;&lt;br /&gt;&lt;span&gt;&gt;&gt; &lt;/span&gt;You could try something like int *p = NULL; *p = 42; that should crash&lt;br /&gt;&lt;span&gt;&gt;&gt; &lt;/span&gt;your service and the restart should occur after the configured time&lt;br /&gt;&lt;span&gt;&gt;&gt; &lt;/span&gt;interval. Defaults to 1 minute IIRC.&lt;/pre&gt;2&gt; Another solution I tried is to create a database watching thread. Instead of aborting from the startup procedure, the watching thread will keep checking the database connection, and notify the main thread when the database is available.&lt;br /&gt;&lt;br /&gt;This approach is working, but it's a little bit overkilling. Everybody knows that the thread should really be avoided unless it's absolutely needed. In my case, if the database is not connected, my program is not workable any way, since I need the information from database to perform a lot of things...&lt;br /&gt;&lt;br /&gt;The final solution I come out is putting the database checking in a while loop, which will check the database connection a configurable times (10 times by default) at start up in every 10 seconds.&lt;br /&gt;&lt;br /&gt;This solution has 2 advantages:&lt;br /&gt;1&gt; The start up procedure of my service won't abort immediately if the database is not available. And in my cases, most of times, the database is available, it's just a little bit slow to come back.&lt;br /&gt;2&gt; If it really failed after trying to connect to the database after certain attempts, it may need some attention anyway.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7462882-872615860962701962?l=gisresearch.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gisresearch.blogspot.com/feeds/872615860962701962/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7462882&amp;postID=872615860962701962' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7462882/posts/default/872615860962701962'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7462882/posts/default/872615860962701962'/><link rel='alternate' type='text/html' href='http://gisresearch.blogspot.com/2007/01/i-have-windows-service-program-which.html' title='I have a windows service program which depends a sql database. Sometimes, when the machine starts and my program tries to connect the database, the da'/><author><name>J.W.</name><uri>http://www.blogger.com/profile/09241601264454722977</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://farm3.static.flickr.com/2116/1856041089_20ef060d43_o.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7462882.post-762527871746571360</id><published>2007-01-21T10:31:00.000-05:00</published><updated>2007-01-21T10:45:09.292-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Programming'/><title type='text'>What makes a good programmer.</title><content type='html'>Having been working as a computer programmer for the past 5 years, I have some thoughts about what makes a good programmer.&lt;br /&gt;&lt;br /&gt;1&amp;gt;&lt;span style="font-weight: bold;"&gt;design patterns&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;I think it's the far most important one, the life of the software depends on how easy you can maintain the software, how easy you can add a new feature, how easy you can modify an existing feature. Every programmer can write some codes, but the difference is how they organize the codes. The seasoned programmer always bears in mind how s/he can maintain it when s/he implements some codes.&lt;br /&gt;&lt;br /&gt;2&amp;gt;&lt;span style="font-weight: bold;"&gt;Language Features&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Familiarity of the languages, including the libraries associated with the particular languages. There are a lot of languages available, C#, C++, Java..., and nobody could be very familiar with each of them, just as nobody could speak every language in the world. But a good programmer has to be very familiar with one or two languages s/he uses in day to day work. Efficiency also comes from this, if you know the language feature well, it's easier for you write clean code.&lt;br /&gt;&lt;br /&gt;I often read code I wrote when I just started to work 5 years ago, and I feel it's ugly, and a lot of them are NOT very sophisticated. Sometimes, an experienced programmer can write two lines of codes which an inexperienced programmer may need write more than 10 lines of code.&lt;br /&gt;&lt;br /&gt;3&amp;gt; &lt;span style="font-weight: bold;"&gt;Algorithms&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;That's the part I missed all. In day to day work, a lot of focuses are on RAD (Rapid Application Development). Most of time, you don't have to think about too much on the underlying algorithm, you'll just find some data structures in the library, rarely you'll have to write something really serious. This kind of work will make smart people dumb because they don't get chance to think deeply.&lt;br /&gt;&lt;br /&gt;4&amp;gt;&lt;span style="font-weight: bold;"&gt; Resource Handling &lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Computer is a shared resource. The computer your program is running also includes a lot of other programs. It means, if you want to use certain resources , you are borrowing some resource from the computer, after using it, you want to give it back to the computer. If you don't , it means other people won't be able to use it.&lt;br /&gt;&lt;br /&gt;The situation has been improved steadily with new technologies or research efforts underway. If you work in a managed world like C# or Java, you have less worry since GC did a lot of work for you. But still, there are a lot of resource the GC won't handle for you automatically, or in other word, you cannot rely on GC to take care for you.&lt;br /&gt;&lt;br /&gt;5&amp;gt; &lt;span style="font-weight: bold;"&gt;Tools&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Making good use of the tools. I know some geeks like to program in notepad, and open a command window to do everything. I admire those people since it reflects that those people really understand what's under the hood. And a lot of times, they can do thing more efficiency.&lt;br /&gt;&lt;br /&gt;For me, like most other people, I like powerful IDEs like VS.Net and Eclipse, even though I don't have much experience in the latter one. Jon Skeet has a very good &lt;a href="http://msmvps.com/blogs/jon.skeet/archive/2005/12/22/79631.aspx"&gt;post&lt;/a&gt; about those two IDEs. I always try not to rely more on shortcuts instead of the mouse in developing. I feel it can improve efficiency much.&lt;br /&gt;&lt;br /&gt;By meaning tools, I also mean those sdk tools, and a lot of third party add-ons. James Avery has a MSDN article about ten &lt;a href="http://msdn.microsoft.com/msdnmag/issues/05/12/VisualStudioAddins/"&gt;VS.Net essential tools&lt;/a&gt;. By making full use of those tools, you can really show a difference with those co-workers who don't use those tools.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7462882-762527871746571360?l=gisresearch.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gisresearch.blogspot.com/feeds/762527871746571360/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7462882&amp;postID=762527871746571360' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7462882/posts/default/762527871746571360'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7462882/posts/default/762527871746571360'/><link rel='alternate' type='text/html' href='http://gisresearch.blogspot.com/2007/01/what-makes-good-programmer.html' title='What makes a good programmer.'/><author><name>J.W.</name><uri>http://www.blogger.com/profile/09241601264454722977</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://farm3.static.flickr.com/2116/1856041089_20ef060d43_o.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7462882.post-5480630593527571461</id><published>2007-01-21T10:30:00.001-05:00</published><updated>2007-01-21T10:45:34.960-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='GMap'/><category scheme='http://www.blogger.com/atom/ns#' term='.Net'/><title type='text'>GMap asp.net control , geocoding, and asynchronous page.</title><content type='html'>I have been playing the &lt;a href="http://gmapsdotnetcontrol.blogspot.com/"&gt;GMap asp.net control&lt;/a&gt; recently, and loved it. I didn't have much experience in asp.net server control, and this gave me a good start to get into some details.&lt;br /&gt;&lt;br /&gt;I wanted to use the geocoder functionalities of the GMap, and did some simple research on that. I firstly tried to use some call back functions. In the class "GServerGeoCoder" I created, i have a match function which sent a Http request over to the server , like this:&lt;br /&gt;&lt;br /&gt;public void Match()&lt;br /&gt;{&lt;br /&gt;IAsyncResult result = (IAsyncResult)geoCoderHttpWebRequest.BeginGetResponse(new AsyncCallback(RespCallback), geoCoderRequestState);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;And in the RespCallBack, I would raise an event GeoCoderResponeReceived which the aspx page registered. I thought it was a good approach, but the problem is that the server control won't render itself in the callback.&lt;br /&gt;&lt;br /&gt;The thread which processed the geocoder request would go ahead to finish the rendering, and it won't wait for the call back result to finish the rending process. And the call back to the aspx page won't cause the server control render itself again. I assume there is a way to do it, but I didn't find it out so far.&lt;br /&gt;&lt;br /&gt;Then, I searched some other ways and found out that asp.net actually has a way to do it called "&lt;b&gt;&lt;a href="http://msdn.microsoft.com/msdnmag/issues/05/10/WickedCode/"&gt;Asynchronous Pages&lt;/a&gt;" &lt;/b&gt;,and this is exactly what I looked for.   By registering some PageAsyncTask,  [Start quoting from &lt;a title="More articles by this author" href="http://msdn.microsoft.com/msdnmag/find/?type=Au&amp;phrase=Jeff%20Prosise&amp;amp;words=exact"&gt;Jeff Prosise&lt;/a&gt; ]"The page undergoes its normal processing lifecycle until shortly after the PreRender event fires. Then ASP.NET calls the Begin method that you registered using AddOnPreRenderCompleteAsync, Furthermore, the Begin method returns an IAsyncResult that lets ASP.NET determine when the asynchronous operation has completed, at which point ASP.NET extracts a thread from the thread pool and calls your End method. After End returns, ASP.NET executes the remaining portion of the page's lifecycle, which includes the rendering phase." [End quoting]&lt;br /&gt;&lt;br /&gt;The whole idea is that we need to postpone the rending process until we get the result back.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7462882-5480630593527571461?l=gisresearch.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gisresearch.blogspot.com/feeds/5480630593527571461/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7462882&amp;postID=5480630593527571461' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7462882/posts/default/5480630593527571461'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7462882/posts/default/5480630593527571461'/><link rel='alternate' type='text/html' href='http://gisresearch.blogspot.com/2007/01/gmap-aspnet-control-geocoding-and.html' title='GMap asp.net control , geocoding, and asynchronous page.'/><author><name>J.W.</name><uri>http://www.blogger.com/profile/09241601264454722977</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://farm3.static.flickr.com/2116/1856041089_20ef060d43_o.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7462882.post-8288218322851962073</id><published>2007-01-21T10:29:00.000-05:00</published><updated>2007-01-21T10:45:56.539-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Programming'/><category scheme='http://www.blogger.com/atom/ns#' term='.Net'/><title type='text'>The magic yield return , Tree enumerators.</title><content type='html'>The yield return is a magic feature introduced in C# 2.0, it makes life lot easier to enumerate the collection. I was working on a tree collection recently, and it involves doing a BFS and DFS.&lt;br /&gt;&lt;br /&gt;Here is the sample code..&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;!-- {\rtf1\ansi\ansicpg\lang1024\noproof1252\uc1 \deff0{\fonttbl{\f0\fnil\fcharset0\fprq1 Courier New;}}{\colortbl;\red0\green0\blue0;\red0\green0\blue255;\red0\green255\blue255;\red0\green255\blue0??;\red255\green0\blue255;\red255\green0\blue0;\red255\green255\blue0;\red255\green255\blue255;??\red0\green0\blue128;\red0\green128\blue128;\red0\green128\blue0;??\red128\green0\blue128;\red128\green0\blue0;\red128\green128\blue0;\red128\green128\blue128;??\red192\green192\blue192;}??\fs20        \cf15 ///\cf11  \cf15 &lt;summary&gt;\par ??\cf0         \cf15 ///\cf11  Gets the depth first node enumerator.\par ??\cf0         \cf15 ///\cf11  \cf15 &lt;/summary&gt;\par ??\cf0         \cf15 ///\cf11  \cf15 &lt;value&gt;\cf11 The depth first node enumerator.\cf15 &lt;/value&gt;\par ??\cf0         \cf2 public\cf0  \cf10 IEnumerable\cf0 &lt;\cf10 DTreeNode\cf0 &lt;t&gt;&gt; DepthFirstNodeEnumerator\par ??        \{\par ??            \cf2 get\par ??\cf0             \{\par ??                \cf2 yield\cf0  \cf2 return\cf0  \cf2 this\cf0 ;\par ??                \cf2 if\cf0  (m_Nodes != \cf2 null\cf0 )\par ??                \{\par ??                    \cf2 foreach\cf0  (\cf10 DTreeNode\cf0 &lt;t&gt; child \cf2 in\cf0  m_Nodes)\par ??                    \{\par ??                        \cf10 IEnumerator\cf0 &lt;\cf10 DTreeNode\cf0 &lt;t&gt;&gt; childEnum = child.DepthFirstNodeEnumerator.GetEnumerator();\par ??                        \cf2 while\cf0  (childEnum.MoveNext())\par ??                            \cf2 yield\cf0  \cf2 return\cf0  childEnum.Current;\par ??                    \}\par ??                \}\par ??            \}\par ??        \}\par ??\par ??        \cf15 ///\cf11  \cf15 &lt;summary&gt;\par ??\cf0         \cf15 ///\cf11  Gets the breadth first node enumerator.\par ??\cf0         \cf15 ///\cf11  \cf15 &lt;/summary&gt;\par ??\cf0         \cf15 ///\cf11  \cf15 &lt;value&gt;\cf11 The breadth first node enumerator.\cf15 &lt;/value&gt;\par ??\cf0         \cf2 public\cf0  \cf10 IEnumerable\cf0 &lt;\cf10 DTreeNode\cf0 &lt;t&gt;&gt; BreadthFirstNodeEnumerator\par ??        \{\par ??            \cf2 get\par ??\cf0             \{\par ??                \cf10 Queue\cf0 &lt;\cf10 DTreeNode\cf0 &lt;t&gt;&gt; todo = \cf2 new\cf0  \cf10 Queue\cf0 &lt;\cf10 DTreeNode\cf0 &lt;t&gt;&gt;();\par ??                todo.Enqueue(\cf2 this\cf0 );\par ??                \cf2 while\cf0  (0 &lt;&gt; node = todo.Dequeue();\par ??                    \cf2 if\cf0  (node.m_Nodes != \cf2 null\cf0 )\par ??                    \{\par ??                        \cf2 foreach\cf0  (\cf10 DTreeNode\cf0 &lt;t&gt; child \cf2 in\cf0  node.m_Nodes)\par ??                            todo.Enqueue(child);\par ??                    \}\par ??                    \cf2 yield\cf0  \cf2 return\cf0  node;\par ??                \}\par ??            \}\par ??        \}\par ??} --&gt;&lt;br /&gt;&lt;div    style="background: white none repeat scroll 0% 50%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;font-family:Courier New;font-size:10pt;color:black;"&gt;&lt;br /&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;  538&lt;/span&gt;        &lt;span style="color:gray;"&gt;///&lt;/span&gt;&lt;span style="color:green;"&gt; &lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;br /&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;  539&lt;/span&gt;         &lt;span style="color:gray;"&gt;///&lt;/span&gt;&lt;span style="color:green;"&gt; Gets the depth first node enumerator.&lt;/span&gt;&lt;/p&gt;&lt;br /&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;  540&lt;/span&gt;         &lt;span style="color:gray;"&gt;///&lt;/span&gt;&lt;span style="color:green;"&gt; &lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;br /&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;  541&lt;/span&gt;         &lt;span style="color:gray;"&gt;///&lt;/span&gt;&lt;span style="color:green;"&gt; &lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;value&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;The depth first node enumerator.&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/value&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;br /&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;  542&lt;/span&gt;         &lt;span style="color:blue;"&gt;public&lt;/span&gt; &lt;span style="color:teal;"&gt;IEnumerable&lt;/span&gt;&amp;lt;&lt;span style="color:teal;"&gt;DTreeNode&lt;/span&gt;&amp;lt;T&amp;gt;&amp;gt; DepthFirstNodeEnumerator&lt;/p&gt;&lt;br /&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;  543&lt;/span&gt;         {&lt;/p&gt;&lt;br /&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;  544&lt;/span&gt;             &lt;span style="color:blue;"&gt;get&lt;/span&gt;&lt;/p&gt;&lt;br /&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;  545&lt;/span&gt;             {&lt;/p&gt;&lt;br /&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;  546&lt;/span&gt;                 &lt;span style="color:blue;"&gt;yield&lt;/span&gt; &lt;span style="color:blue;"&gt;return&lt;/span&gt; &lt;span style="color:blue;"&gt;this&lt;/span&gt;;&lt;/p&gt;&lt;br /&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;  547&lt;/span&gt;                 &lt;span style="color:blue;"&gt;if&lt;/span&gt; (m_Nodes != &lt;span style="color:blue;"&gt;null&lt;/span&gt;)&lt;/p&gt;&lt;br /&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;  548&lt;/span&gt;                 {&lt;/p&gt;&lt;br /&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;  549&lt;/span&gt;                     &lt;span style="color:blue;"&gt;foreach&lt;/span&gt; (&lt;span style="color:teal;"&gt;DTreeNode&lt;/span&gt;&amp;lt;T&amp;gt; child &lt;span style="color:blue;"&gt;in&lt;/span&gt; m_Nodes)&lt;/p&gt;&lt;br /&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;  550&lt;/span&gt;                     {&lt;/p&gt;&lt;br /&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;  551&lt;/span&gt;                         &lt;span style="color:teal;"&gt;IEnumerator&lt;/span&gt;&amp;lt;&lt;span style="color:teal;"&gt;DTreeNode&lt;/span&gt;&amp;lt;T&amp;gt;&amp;gt; childEnum = child.DepthFirstNodeEnumerator.GetEnumerator();&lt;/p&gt;&lt;br /&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;  552&lt;/span&gt;                         &lt;span style="color:blue;"&gt;while&lt;/span&gt; (childEnum.MoveNext())&lt;/p&gt;&lt;br /&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;  553&lt;/span&gt;                             &lt;span style="color:blue;"&gt;yield&lt;/span&gt; &lt;span style="color:blue;"&gt;return&lt;/span&gt; childEnum.Current;&lt;/p&gt;&lt;br /&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;  554&lt;/span&gt;                     }&lt;/p&gt;&lt;br /&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;  555&lt;/span&gt;                 }&lt;/p&gt;&lt;br /&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;  556&lt;/span&gt;             }&lt;/p&gt;&lt;br /&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;  557&lt;/span&gt;         }&lt;/p&gt;&lt;br /&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;  558&lt;/span&gt; &lt;/p&gt;&lt;br /&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;  559&lt;/span&gt;         &lt;span style="color:gray;"&gt;///&lt;/span&gt;&lt;span style="color:green;"&gt; &lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;br /&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;  560&lt;/span&gt;         &lt;span style="color:gray;"&gt;///&lt;/span&gt;&lt;span style="color:green;"&gt; Gets the breadth first node enumerator.&lt;/span&gt;&lt;/p&gt;&lt;br /&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;  561&lt;/span&gt;         &lt;span style="color:gray;"&gt;///&lt;/span&gt;&lt;span style="color:green;"&gt; &lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;br /&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;  562&lt;/span&gt;         &lt;span style="color:gray;"&gt;///&lt;/span&gt;&lt;span style="color:green;"&gt; &lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;value&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;The breadth first node enumerator.&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/value&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;br /&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;  563&lt;/span&gt;         &lt;span style="color:blue;"&gt;public&lt;/span&gt; &lt;span style="color:teal;"&gt;IEnumerable&lt;/span&gt;&amp;lt;&lt;span style="color:teal;"&gt;DTreeNode&lt;/span&gt;&amp;lt;T&amp;gt;&amp;gt; BreadthFirstNodeEnumerator&lt;/p&gt;&lt;br /&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;  564&lt;/span&gt;         {&lt;/p&gt;&lt;br /&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;  565&lt;/span&gt;             &lt;span style="color:blue;"&gt;get&lt;/span&gt;&lt;/p&gt;&lt;br /&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;  566&lt;/span&gt;             {&lt;/p&gt;&lt;br /&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;  567&lt;/span&gt;                 &lt;span style="color:teal;"&gt;Queue&lt;/span&gt;&amp;lt;&lt;span style="color:teal;"&gt;DTreeNode&lt;/span&gt;&amp;lt;T&amp;gt;&amp;gt; todo = &lt;span style="color:blue;"&gt;new&lt;/span&gt; &lt;span style="color:teal;"&gt;Queue&lt;/span&gt;&amp;lt;&lt;span style="color:teal;"&gt;DTreeNode&lt;/span&gt;&amp;lt;T&amp;gt;&amp;gt;();&lt;/p&gt;&lt;br /&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;  568&lt;/span&gt;                 todo.Enqueue(&lt;span style="color:blue;"&gt;this&lt;/span&gt;);&lt;/p&gt;&lt;br /&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;  569&lt;/span&gt;                 &lt;span style="color:blue;"&gt;while&lt;/span&gt; (0 &amp;lt; todo.Count)&lt;/p&gt;&lt;br /&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;  570&lt;/span&gt;                 {&lt;/p&gt;&lt;br /&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;  571&lt;/span&gt;                     &lt;span style="color:teal;"&gt;DTreeNode&lt;/span&gt;&amp;lt;T&amp;gt; node = todo.Dequeue();&lt;/p&gt;&lt;br /&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;  572&lt;/span&gt;                     &lt;span style="color:blue;"&gt;if&lt;/span&gt; (node.m_Nodes != &lt;span style="color:blue;"&gt;null&lt;/span&gt;)&lt;/p&gt;&lt;br /&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;  573&lt;/span&gt;                     {&lt;/p&gt;&lt;br /&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;  574&lt;/span&gt;                         &lt;span style="color:blue;"&gt;foreach&lt;/span&gt; (&lt;span style="color:teal;"&gt;DTreeNode&lt;/span&gt;&amp;lt;T&amp;gt; child &lt;span style="color:blue;"&gt;in&lt;/span&gt; node.m_Nodes)&lt;/p&gt;&lt;br /&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;  575&lt;/span&gt;                             todo.Enqueue(child);&lt;/p&gt;&lt;br /&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;  576&lt;/span&gt;                     }&lt;/p&gt;&lt;br /&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;  577&lt;/span&gt;                     &lt;span style="color:blue;"&gt;yield&lt;/span&gt; &lt;span style="color:blue;"&gt;return&lt;/span&gt; node;&lt;/p&gt;&lt;br /&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;  578&lt;/span&gt;                 }&lt;/p&gt;&lt;br /&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;  579&lt;/span&gt;             }&lt;/p&gt;&lt;br /&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;  580&lt;/span&gt;         }&lt;/p&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;The point of iterators is to allow the easy implementation of enumerators. Where a method needs to return either an enumerator or an enumerable class for an ordered list of items, it is written so as to return each item in its correct order using the ‘yield’ statement.&lt;br /&gt;&lt;br /&gt;The magic yield will keep a state information in the enumeration, so it always remembers where to start in the next loop.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7462882-8288218322851962073?l=gisresearch.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gisresearch.blogspot.com/feeds/8288218322851962073/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7462882&amp;postID=8288218322851962073' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7462882/posts/default/8288218322851962073'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7462882/posts/default/8288218322851962073'/><link rel='alternate' type='text/html' href='http://gisresearch.blogspot.com/2007/01/magic-yield-return-tree-enumerators.html' title='The magic yield return , Tree enumerators.'/><author><name>J.W.</name><uri>http://www.blogger.com/profile/09241601264454722977</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://farm3.static.flickr.com/2116/1856041089_20ef060d43_o.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7462882.post-8514154224194087266</id><published>2007-01-21T10:28:00.000-05:00</published><updated>2007-01-21T10:46:15.500-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Life'/><title type='text'>The trip.</title><content type='html'>&lt;p&gt;I have been on vacation since last week, and traveled Phoenix, Las Vegas, San Francisco, Los Angeles, and San Diego. It was a great trip, partly because I really haven't been in those parts of the country that much.&lt;/p&gt; &lt;p&gt;The best city in my view is San Francisco, including its suburbs. The weather is so nice, comparing with the cold Columbus. I was told the summer is also very nice.&lt;/p&gt; &lt;p&gt;I also got to meet a lot of friends I haven't seen for years. They are doing very well, and I am really happy for them. &lt;/p&gt; &lt;p&gt;Now, I am back in Phoenix, and will spend most of the time in hotel and have some time to read some books.&lt;/p&gt; &lt;p&gt; I had a new friend in this trip - Microsoft Streets and Trips with the GPS receiver. I am very happy with it. The problem with the traditional maps is that sometimes, it's harder to locate where you are, but with the GPS, you are always aware the current location. That makes a big difference. And the map is pretty accurate. The only time I have some issue was when I drove in the skyscrapers in SF, the GPS signal seemed to be blocked by the buildings a little bit.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7462882-8514154224194087266?l=gisresearch.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gisresearch.blogspot.com/feeds/8514154224194087266/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7462882&amp;postID=8514154224194087266' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7462882/posts/default/8514154224194087266'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7462882/posts/default/8514154224194087266'/><link rel='alternate' type='text/html' href='http://gisresearch.blogspot.com/2007/01/trip.html' title='The trip.'/><author><name>J.W.</name><uri>http://www.blogger.com/profile/09241601264454722977</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://farm3.static.flickr.com/2116/1856041089_20ef060d43_o.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7462882.post-1677753964084680231</id><published>2007-01-21T10:27:00.000-05:00</published><updated>2007-01-21T10:46:41.343-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Programming'/><category scheme='http://www.blogger.com/atom/ns#' term='.Net'/><title type='text'>Implement a queue using an array...</title><content type='html'>&lt;p&gt;I have been reviewing some basic data structure lately. The queue is one of the basic data structure, just as other data structure, you can use the array or the link list to implement it.&lt;/p&gt; &lt;p&gt;When using an array to implement the the queue, there are two pointers, one points to the head, and the other points to the end. If we have array of size N to implement an list with N elements. We will have 0&amp;lt;=head&amp;lt;N, and 0&amp;lt;=tail&amp;lt;N, and the difference between head and tail satisfies 0&amp;lt;=(head-tail)mod N &amp;lt;N. There are only n distinct differences, with queue length 0, 1, 2, ... , N-1. But the queue could have N elements too, it means that the number of the enumerations(N+1) of the queue is larger than what the underlying array can offer. &lt;/p&gt; &lt;p&gt;Actually, when the array is empty (the queue has 0 element), the head and the tail points to the same position, and when the array is full, the head and the tail points to the same position too. So, we cannot tell whether the list is empty of full solely based on the head and tail position.&lt;/p&gt; &lt;p&gt;For example, when the queue is just created, the head points to 0 piston, and the tail points to the N-1 position in the array, and when we add the first element, the tail position will move to the first element. If we keep adding 10 elements, then we get to a point the tail position will point to the 10th element again. Then the head and tail position actually points to the exact same position as the empty queue.&lt;/p&gt; &lt;p&gt;There are two options for dealing with this problem. The first is to limit the number of elements in the queue to be at most n-1. The other is to use another member variable , count, to keep tract explicitly of the actual number of elements in the queue rather than to infer the number from the head and tail variables. Both are valid options.&lt;/p&gt; &lt;p&gt;In the first option, we let the tail point to the 0 element, and the head point to the N position. So, if we move the head right, then we'll reach the tail, that's the &lt;strong&gt;empty&lt;/strong&gt; situation. On the other hand, if we have a &lt;strong&gt;full&lt;/strong&gt; queue, we move the tail right, we'll reach the head. &lt;/p&gt; &lt;p&gt;The empty condition is happening when head/N==tail/N. And the full condition is happening tail+1==head.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7462882-1677753964084680231?l=gisresearch.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gisresearch.blogspot.com/feeds/1677753964084680231/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7462882&amp;postID=1677753964084680231' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7462882/posts/default/1677753964084680231'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7462882/posts/default/1677753964084680231'/><link rel='alternate' type='text/html' href='http://gisresearch.blogspot.com/2007/01/implement-queue-using-array.html' title='Implement a queue using an array...'/><author><name>J.W.</name><uri>http://www.blogger.com/profile/09241601264454722977</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://farm3.static.flickr.com/2116/1856041089_20ef060d43_o.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7462882.post-8015975973169357491</id><published>2007-01-21T10:25:00.000-05:00</published><updated>2007-01-21T10:27:08.402-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Programming'/><category scheme='http://www.blogger.com/atom/ns#' term='.Net'/><title type='text'>The vm size on the task manager is confusing.</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp0.blogger.com/_skGtCbVaJ2o/RZlBVUjsG1I/AAAAAAAAAAU/_Ln_y8gYgRg/s1600-h/pesize.GIF"&gt;&lt;img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer;" src="http://bp0.blogger.com/_skGtCbVaJ2o/RZlBVUjsG1I/AAAAAAAAAAU/_Ln_y8gYgRg/s320/pesize.GIF" alt="" id="BLOGGER_PHOTO_ID_5015111494605216594" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp0.blogger.com/_skGtCbVaJ2o/RZlBNUjsG0I/AAAAAAAAAAM/wKxGllj6lOo/s1600-h/memorysize.GIF"&gt;&lt;img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer;" src="http://bp0.blogger.com/_skGtCbVaJ2o/RZlBNUjsG0I/AAAAAAAAAAM/wKxGllj6lOo/s320/memorysize.GIF" alt="" id="BLOGGER_PHOTO_ID_5015111357166263106" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;p&gt;Everybody who has taken a course of Operating system knows the difference between the virtual memory and physical memory. There is a good definition &lt;a href="http://www.cheap-computers-guide.com/computer-related-glossary.html"&gt;here&lt;/a&gt; : Virtual (or logical) memory is a concept that, when implemented by a computer and its operating system, allows programmers to use a very large range of memory or storage addresses for stored data. The computing system maps the programmer's virtual addresses to real hardware storage addresses. Usually, the programmer is freed from having to be concerned about the availability of data storage.&lt;/p&gt; &lt;p&gt;And the physical memory is the memory actually used by the process right now. So normally, you would think that virtual memory used by one process should be larger than its physical memory.&lt;/p&gt; &lt;p&gt;But if you open the task manager,and compare the size of the virtual memory and physical memory, you will get a different answer.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;The vm size is actually smaller than the physical memory size. The "VM size"  used by the task manager is pretty misleading.&lt;/p&gt; &lt;p&gt;The VM is actually the "Private Bytes" used by the popular process explorer, which are part of the VM, but they exclude the memory allocated by the system. The process explorer depicts a much better picture of the system state.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7462882-8015975973169357491?l=gisresearch.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gisresearch.blogspot.com/feeds/8015975973169357491/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7462882&amp;postID=8015975973169357491' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7462882/posts/default/8015975973169357491'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7462882/posts/default/8015975973169357491'/><link rel='alternate' type='text/html' href='http://gisresearch.blogspot.com/2007/01/vm-size-on-task-manager-is-confusing.html' title='The vm size on the task manager is confusing.'/><author><name>J.W.</name><uri>http://www.blogger.com/profile/09241601264454722977</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://farm3.static.flickr.com/2116/1856041089_20ef060d43_o.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://bp0.blogger.com/_skGtCbVaJ2o/RZlBVUjsG1I/AAAAAAAAAAU/_Ln_y8gYgRg/s72-c/pesize.GIF' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7462882.post-2177994480761239847</id><published>2007-01-21T10:24:00.001-05:00</published><updated>2007-01-21T10:24:40.914-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Programming'/><category scheme='http://www.blogger.com/atom/ns#' term='.Net'/><title type='text'>Using FxCop</title><content type='html'>&lt;p&gt;I have downloaded the FxCop long time ago, but really didn't use it too much until recently.&lt;/p&gt; &lt;p&gt;I think every .Net programmer really should run it on a routine basis. It's just too important to ignore. When I firstly ran it on my utilities project, it gave me over 3400 warnings, while the compiler even didn't give me a single warning. &lt;/p&gt; &lt;p&gt;I am not saying all those warnings are valid. One of my text file which is embedded in the resource is a soundex index file, and it has a lot of unrecognized words in that. So, it gives a lot of errors in the Microsoft.Naming. After I remove the files , the errors dropped about half. Still, it's quite a lot. &lt;/p&gt; &lt;p&gt;I spent about 10 hours go through those warnings, and a lot of those warnings are valid warnings, such as IDispose are not implement correctly, explicit interface implementations should be changed to conform to the standards.&lt;/p&gt; &lt;p&gt;After I go through those warnings line by line, it teaches me a lot what I should code according to the standard. A lot of stuff which I normally never pay attention to actually deserve a lot of attention.&lt;/p&gt; &lt;p&gt;Good stuff, strongly recommended.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7462882-2177994480761239847?l=gisresearch.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gisresearch.blogspot.com/feeds/2177994480761239847/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7462882&amp;postID=2177994480761239847' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7462882/posts/default/2177994480761239847'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7462882/posts/default/2177994480761239847'/><link rel='alternate' type='text/html' href='http://gisresearch.blogspot.com/2007/01/using-fxcop.html' title='Using FxCop'/><author><name>J.W.</name><uri>http://www.blogger.com/profile/09241601264454722977</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://farm3.static.flickr.com/2116/1856041089_20ef060d43_o.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7462882.post-115481872904889468</id><published>2006-08-05T18:57:00.000-04:00</published><updated>2006-08-05T18:58:49.656-04:00</updated><title type='text'>Adaptor pattern</title><content type='html'>Adapter pattern applies to the &lt;span&gt;situation&lt;/span&gt; where you want to adapt a third-party class into your own domain. The third party component will has no &lt;span&gt;knowledge&lt;/span&gt; of your design, so the only way you can use to create a an adapter class to use.&lt;br /&gt;&lt;br /&gt;There are two ways to in this adaption approach. One is called "Class Adaptor". In this case, a multiple inheritance will be used. Normally, the class in your design will inherit from both the base class and the class you want to adapt. Another approach is called "Object Adaptor", in this approach, you will declare an object  of the &lt;span&gt;adaptee&lt;/span&gt; type in your adaptor class. (In some languages like c# which doesn't &lt;span&gt;support&lt;/span&gt; the &lt;span&gt;multiple&lt;/span&gt; inheritance, this may be the only choice available.)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7462882-115481872904889468?l=gisresearch.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gisresearch.blogspot.com/feeds/115481872904889468/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7462882&amp;postID=115481872904889468' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7462882/posts/default/115481872904889468'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7462882/posts/default/115481872904889468'/><link rel='alternate' type='text/html' href='http://gisresearch.blogspot.com/2006/08/adaptor-pattern.html' title='Adaptor pattern'/><author><name>J.W.</name><uri>http://www.blogger.com/profile/09241601264454722977</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://farm3.static.flickr.com/2116/1856041089_20ef060d43_o.jpg'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7462882.post-114899541652600456</id><published>2006-05-30T09:21:00.000-04:00</published><updated>2007-01-21T10:47:23.564-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Programming'/><category scheme='http://www.blogger.com/atom/ns#' term='.Net'/><title type='text'>C# Delegate.</title><content type='html'>Each delegate object is really a wrapper around a method and an object to be operated on when the method is called.&lt;br /&gt;&lt;br /&gt;The constructor takes an object and IntPtr value, in the constructor, these two arguments are saved in _target and _methodPtr private fields. &lt;div class="tags"&gt;Tags:GISResearch&lt;ul&gt;&lt;li&gt;&lt;a href="http://del.icio.us/GISResearch/GISResearch+Programming" rel="tag"&gt;Programming&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7462882-114899541652600456?l=gisresearch.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gisresearch.blogspot.com/feeds/114899541652600456/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7462882&amp;postID=114899541652600456' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7462882/posts/default/114899541652600456'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7462882/posts/default/114899541652600456'/><link rel='alternate' type='text/html' href='http://gisresearch.blogspot.com/2006/05/c-delegate.html' title='C# Delegate.'/><author><name>J.W.</name><uri>http://www.blogger.com/profile/09241601264454722977</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://farm3.static.flickr.com/2116/1856041089_20ef060d43_o.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7462882.post-114822082477337496</id><published>2006-05-21T10:02:00.000-04:00</published><updated>2006-05-21T10:13:44.866-04:00</updated><title type='text'>FreshTag stop working.</title><content type='html'>I use &lt;a href="http://ghill.customer.netspace.net.au/freshtags/index.html"&gt;FreshTags&lt;/a&gt;  to help organize my blogs since the blog service I use (www.blogger.com) lacks the built-in support for this functionality. Honestly, I think the blogger service is kind of far behind of the other services offered by google.&lt;br /&gt;&lt;br /&gt;For mysterious reason, the freshtags stop working two days ago, and I tried to use &lt;a href="http://ghill.customer.netspace.net.au/freshtags/build.html"&gt;build page&lt;/a&gt;  to experience different settings. It seems the samples it offered work perfectly, but after I change certain settings to mine, it just stops working.&lt;br /&gt;&lt;br /&gt;I am not familar with the javascript code, and the javascript code the freshtags uses seems pretty complicated to me, so I didn't try to examine the code at the beginning. And it proved wrong, I should look into the code at the very beginning.&lt;br /&gt;&lt;br /&gt;The issue is somehow, del.icio.us starts to offer all its feed only to query built in lowercase. At the beginning, I querid the tags using the upper case like this : &lt;a href="http://del.icio.us/feeds/json/tags/yuren1978/GISresearch?sort=freq&amp;count=100"&gt;http://del.icio.us/feeds/json/tags/yuren1978/GISresearch?sort=freq&amp;amp;count=100,&lt;/a&gt;&lt;br /&gt;And after I changed this to the lower case : &lt;a href="http://del.icio.us/feeds/json/tags/yuren1978/gisresearch?sort=freq&amp;count=100,"&gt;http://del.icio.us/feeds/json/tags/yuren1978/gisresearch?sort=freq&amp;amp;count=100, &lt;/a&gt;&lt;br /&gt;Those tags are returned in correct way.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="tags"&gt;yuren1978&lt;ul&gt;&lt;li&gt;&lt;a href="http://del.icio.us/yuren1978/GISResearch+Programming" rel="tag"&gt;Programming&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7462882-114822082477337496?l=gisresearch.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gisresearch.blogspot.com/feeds/114822082477337496/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7462882&amp;postID=114822082477337496' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7462882/posts/default/114822082477337496'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7462882/posts/default/114822082477337496'/><link rel='alternate' type='text/html' href='http://gisresearch.blogspot.com/2006/05/freshtag-stop-working.html' title='FreshTag stop working.'/><author><name>J.W.</name><uri>http://www.blogger.com/profile/09241601264454722977</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://farm3.static.flickr.com/2116/1856041089_20ef060d43_o.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7462882.post-114803775291185361</id><published>2006-05-19T07:15:00.000-04:00</published><updated>2006-05-19T08:06:50.920-04:00</updated><title type='text'>Private and GAC deployment.</title><content type='html'>I did a little test over the .Net dll deployment testing two nights ago. I thought I needed to write it down.&lt;br /&gt;&lt;br /&gt;The thing confused me a little bit is if I install the same version of a dll both in the GAC and Private  path ( the application path), will the application look for the dll in the GAC or Private Path.&lt;br /&gt;&lt;br /&gt;I made a simple test dll, and there is a test method which will display a message box. In the dll which I depoloyed to GAC, I will disaplay a message box "Called from GAC", in the private deployed dll, I will display a message box "Called from Local".&lt;br /&gt;&lt;br /&gt;I also made a simple test application which will refer to the test dll.&lt;br /&gt;&lt;br /&gt;If I install the dll into GAC using the GACUtil /i, it will dispaly the following message box.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://photos1.blogger.com/blogger/7117/460/1600/Called%20From%20GAC.gif"&gt;&lt;img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer;" src="http://photos1.blogger.com/blogger/7117/460/320/Called%20From%20GAC.gif" alt="" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;However, if I unistall the GAC , and then the test application will call the dll from the local private path, then the following message box will be displayed.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://photos1.blogger.com/blogger/7117/460/1600/Called%20From%20Local.gif"&gt;&lt;img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer;" src="http://photos1.blogger.com/blogger/7117/460/320/Called%20From%20Local.gif" alt="" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Conclusion, if an assembly is deployed both in the GAC and privately, the one in the GAC will be called firstly.&lt;br /&gt;&lt;div class="tags"&gt;Tags:GISResearch&lt;ul&gt;&lt;li&gt;&lt;a href="http://del.icio.us/GISResearch/GISResearch+Programming" rel="tag"&gt;Programming&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7462882-114803775291185361?l=gisresearch.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gisresearch.blogspot.com/feeds/114803775291185361/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7462882&amp;postID=114803775291185361' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7462882/posts/default/114803775291185361'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7462882/posts/default/114803775291185361'/><link rel='alternate' type='text/html' href='http://gisresearch.blogspot.com/2006/05/private-and-gac-deployment.html' title='Private and GAC deployment.'/><author><name>J.W.</name><uri>http://www.blogger.com/profile/09241601264454722977</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://farm3.static.flickr.com/2116/1856041089_20ef060d43_o.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7462882.post-114789147000874948</id><published>2006-05-17T14:43:00.000-04:00</published><updated>2006-05-17T14:44:30.346-04:00</updated><title type='text'>Non-generic - Generic mapping.</title><content type='html'>&lt;table class="data"&gt;&lt;tbody&gt;&lt;tr valign="top"&gt;&lt;td class="data" width="55%"&gt;Comparer&lt;t&gt;&lt;/td&gt; &lt;td class="data" width="45%"&gt;Comparer&lt;/td&gt; &lt;/tr&gt;  &lt;tr valign="top"&gt; &lt;td class="data" width="55%"&gt;Dictionary&lt;k,t&gt; &lt;/td&gt; &lt;td class="data" width="45%"&gt;HashTable&lt;/td&gt; &lt;/tr&gt;  &lt;tr valign="top"&gt; &lt;td class="data" width="55%"&gt;LinkedList&lt;t&gt;&lt;/td&gt; &lt;td class="data" width="45%"&gt;-&lt;/td&gt; &lt;/tr&gt;  &lt;tr valign="top"&gt; &lt;td class="data" width="55%"&gt;List&lt;t&gt; &lt;/td&gt; &lt;td class="data" width="45%"&gt;ArrayList&lt;/td&gt; &lt;/tr&gt;  &lt;tr valign="top"&gt; &lt;td class="data" width="55%"&gt;Queue&lt;t&gt; &lt;/td&gt; &lt;td class="data" width="45%"&gt;Queue&lt;/td&gt; &lt;/tr&gt;  &lt;tr valign="top"&gt; &lt;td class="data" width="55%"&gt;SortedDictionary&lt;k,t&gt; &lt;/td&gt; &lt;td class="data" width="45%"&gt;SortedList&lt;/td&gt; &lt;/tr&gt;  &lt;tr valign="top"&gt; &lt;td class="data" width="55%"&gt;Stack&lt;t&gt; &lt;/td&gt; &lt;td class="data" width="45%"&gt;Stack&lt;/td&gt; &lt;/tr&gt;  &lt;tr valign="top"&gt; &lt;td class="data" width="55%"&gt;ICollection&lt;t&gt; &lt;/td&gt; &lt;td class="data" width="45%"&gt;ICollection&lt;/td&gt; &lt;/tr&gt;  &lt;tr valign="top"&gt; &lt;td class="data" width="55%"&gt;IComparable&lt;t&gt; &lt;/td&gt; &lt;td class="data" width="45%"&gt;System.IComparable&lt;/td&gt; &lt;/tr&gt;  &lt;tr valign="top"&gt; &lt;td class="data" width="55%"&gt;IDictionary&lt;k,t&gt; &lt;/td&gt; &lt;td class="data" width="45%"&gt;IDictionary  &lt;/td&gt; &lt;/tr&gt;  &lt;tr valign="top"&gt; &lt;td class="data" width="55%"&gt;IEnumerable&lt;t&gt; &lt;/td&gt; &lt;td class="data" width="45%"&gt;IEnumerable&lt;/td&gt; &lt;/tr&gt;  &lt;tr valign="top"&gt; &lt;td class="data" width="55%"&gt;IEnumerator&lt;t&gt; &lt;/td&gt; &lt;td class="data" width="45%"&gt;IEnumerator&lt;/td&gt; &lt;/tr&gt;  &lt;tr valign="top"&gt; &lt;td class="data" width="55%"&gt;IList&lt;t&gt; &lt;/td&gt; &lt;td class="data" width="45%"&gt;IList&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;  &lt;div class="tags"&gt;Tags:GISResearch&lt;ul&gt;&lt;li&gt;&lt;a href="http://del.icio.us/GISResearch/GISResearch+Programming." rel="tag"&gt;Programming.&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7462882-114789147000874948?l=gisresearch.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gisresearch.blogspot.com/feeds/114789147000874948/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7462882&amp;postID=114789147000874948' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7462882/posts/default/114789147000874948'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7462882/posts/default/114789147000874948'/><link rel='alternate' type='text/html' href='http://gisresearch.blogspot.com/2006/05/non-generic-generic-mapping.html' title='Non-generic - Generic mapping.'/><author><name>J.W.</name><uri>http://www.blogger.com/profile/09241601264454722977</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://farm3.static.flickr.com/2116/1856041089_20ef060d43_o.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7462882.post-114783211214148202</id><published>2006-05-16T22:12:00.000-04:00</published><updated>2006-05-16T22:15:12.406-04:00</updated><title type='text'>Love the DPack.</title><content type='html'>&lt;a href="http://www.usysware.com/dpack/"&gt;DPack&lt;/a&gt;. http://www.usysware.com/dpack/&lt;br /&gt;&lt;br /&gt;The most useful features missing in Visual Studio.&lt;br /&gt;&lt;br /&gt;Alt + S : Solution Browser.&lt;br /&gt;Alt + U: File Browser.&lt;br /&gt;Alt + G: Code Browser.&lt;br /&gt;&lt;br /&gt;This will increase code efficiency dramatically.&lt;br /&gt;&lt;br /&gt;Love the DPack. Also on my favorites are GhostDoc, and SmartPaste.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7462882-114783211214148202?l=gisresearch.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gisresearch.blogspot.com/feeds/114783211214148202/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7462882&amp;postID=114783211214148202' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7462882/posts/default/114783211214148202'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7462882/posts/default/114783211214148202'/><link rel='alternate' type='text/html' href='http://gisresearch.blogspot.com/2006/05/love-dpack.html' title='Love the DPack.'/><author><name>J.W.</name><uri>http://www.blogger.com/profile/09241601264454722977</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://farm3.static.flickr.com/2116/1856041089_20ef060d43_o.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7462882.post-114764733364014928</id><published>2006-05-14T18:52:00.000-04:00</published><updated>2006-05-14T19:02:07.800-04:00</updated><title type='text'>A good web programmer needs.</title><content type='html'>1. Good understading of javascript.&lt;br /&gt;2. Good understanding of CSS.&lt;br /&gt;3. Good understanding of Photoshop.&lt;br /&gt;4. Good understanding of Database.&lt;br /&gt;5. Good understanding of server-side programming like asp.net.     &lt;div class="tags"&gt;GISResearch&lt;ul&gt;&lt;li&gt;&lt;a href="http://del.icio.us/yuren1978/GISResearch+Programming" rel="tag"&gt;Programming&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7462882-114764733364014928?l=gisresearch.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gisresearch.blogspot.com/feeds/114764733364014928/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7462882&amp;postID=114764733364014928' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7462882/posts/default/114764733364014928'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7462882/posts/default/114764733364014928'/><link rel='alternate' type='text/html' href='http://gisresearch.blogspot.com/2006/05/good-web-programmer-needs.html' title='A good web programmer needs.'/><author><name>J.W.</name><uri>http://www.blogger.com/profile/09241601264454722977</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://farm3.static.flickr.com/2116/1856041089_20ef060d43_o.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7462882.post-114748042751921354</id><published>2006-05-12T20:20:00.000-04:00</published><updated>2006-05-14T19:06:41.500-04:00</updated><title type='text'>You cannot simply pass the reference to user control.</title><content type='html'>We have a program which will host multiple map controls, and each map control will have its own legend.  It's fine to host muliple maps on different tabs, but it's a little bit tricky to host multiple legends.  The end user will only want to see the  legend associated with  the current active map.&lt;br /&gt;&lt;br /&gt;The first approach I tried is to create a form-level legend, and also create each legend inside each map control. And when the map becomes visible, I will do something like this:&lt;br /&gt;frmMain.legend = currentMap.legend.&lt;br /&gt;frmMain.Legend.Refresh().&lt;br /&gt;&lt;br /&gt;I thought this will make the frmMain.legend point to the active map legend, and draw the active map legend.&lt;br /&gt;&lt;br /&gt;Actually, this is not the case.  Simple reference passing won't make the active map legend become the visible legend. And the OnPaint method of the active map won't be called. The paint message will still be sent to original legend.&lt;br /&gt;&lt;br /&gt;This issue looks simple, but does take me a while to figure it out.&lt;br /&gt;&lt;div class="tags"&gt;GISResearch&lt;br /&gt;&lt;ul&gt; &lt;li&gt;&lt;a href="http://del.icio.us/GISResearch/GISResearch+Programming" rel="tag"&gt;Programming&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7462882-114748042751921354?l=gisresearch.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gisresearch.blogspot.com/feeds/114748042751921354/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7462882&amp;postID=114748042751921354' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7462882/posts/default/114748042751921354'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7462882/posts/default/114748042751921354'/><link rel='alternate' type='text/html' href='http://gisresearch.blogspot.com/2006/05/you-cannot-simply-pass-reference-to.html' title='You cannot simply pass the reference to user control.'/><author><name>J.W.</name><uri>http://www.blogger.com/profile/09241601264454722977</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://farm3.static.flickr.com/2116/1856041089_20ef060d43_o.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7462882.post-114616010471721536</id><published>2006-04-27T13:47:00.000-04:00</published><updated>2006-05-14T20:01:05.086-04:00</updated><title type='text'>Error Handling:</title><content type='html'>Error Handling:&lt;br /&gt;&lt;br /&gt;There are two ways to hanlde the error, one is check the return code of each function, and based on the code returned,  determine whether to continue or abort the program.&lt;br /&gt;&lt;br /&gt;The other way is to throw an exception , and catch it in the central place, and then determine the appropriate behavior from there.&lt;br /&gt;&lt;br /&gt;Thread consideration:&lt;br /&gt;Exceptions should be handled in each sperate thread, if an exception is thrown in a different thread, and not catched in the same thread, it will disapper sliently, and will cause confusion in trouble shooting the issue.&lt;br /&gt;&lt;br /&gt;  &lt;div class="tags"&gt;GISResearch&lt;ul&gt;&lt;li&gt;&lt;a href="http://del.icio.us/yuren1978/GISResearch+Programming" rel="tag"&gt;Programming&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7462882-114616010471721536?l=gisresearch.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gisresearch.blogspot.com/feeds/114616010471721536/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7462882&amp;postID=114616010471721536' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7462882/posts/default/114616010471721536'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7462882/posts/default/114616010471721536'/><link rel='alternate' type='text/html' href='http://gisresearch.blogspot.com/2006/04/error-handling.html' title='Error Handling:'/><author><name>J.W.</name><uri>http://www.blogger.com/profile/09241601264454722977</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://farm3.static.flickr.com/2116/1856041089_20ef060d43_o.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7462882.post-114571814572371000</id><published>2006-04-22T10:54:00.000-04:00</published><updated>2006-05-14T18:08:12.276-04:00</updated><title type='text'>Status watching thread  in windows services.</title><content type='html'>I have a windows service program which needs to integrate with another vendor's program. The thing troubling me is that i cannot set up a good test environment with them.  The only thing I can do is logging every error my program encounters.&lt;br /&gt;&lt;br /&gt;Since it's running as a windows service, so it won't stop even it finds some errors, and the loop just continues running.  I put this service on a client's machine, and it generates 2 GB log data in one day. It's pretty embarassing.&lt;br /&gt;&lt;br /&gt;So, what I ends up is to create another status watching thread monitoring the log file it generates, if it finds out the log file size is exceeding the certain size, it will send a stop message to the ServieMain() thread, which will stop the service. &lt;div class="tags"&gt;GISResearch&lt;ul&gt;&lt;li&gt;&lt;a href="http://del.icio.us/GISResearch/GISResearch+Programming" rel="tag"&gt;Programming&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7462882-114571814572371000?l=gisresearch.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gisresearch.blogspot.com/feeds/114571814572371000/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7462882&amp;postID=114571814572371000' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7462882/posts/default/114571814572371000'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7462882/posts/default/114571814572371000'/><link rel='alternate' type='text/html' href='http://gisresearch.blogspot.com/2006/04/status-watching-thread-in-windows.html' title='Status watching thread  in windows services.'/><author><name>J.W.</name><uri>http://www.blogger.com/profile/09241601264454722977</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://farm3.static.flickr.com/2116/1856041089_20ef060d43_o.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7462882.post-114571377269927332</id><published>2006-04-22T09:21:00.000-04:00</published><updated>2006-04-22T10:46:19.403-04:00</updated><title type='text'>How ATL supports windows service.</title><content type='html'>If you want to create a service based on the ATL library, you normally will inherit the service from CAtlServiceModuleT which is included in atlbase.h&lt;br /&gt;&lt;br /&gt;template &lt;class&gt;&lt;br /&gt;class ATL_NO_VTABLE CAtlServiceModuleT : public CAtlExeModuleT&lt;t&gt;&lt;br /&gt;{&lt;br /&gt;......&lt;br /&gt;   int WinMain(int nShowCmd) throw()&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;When the  &lt;span style=";font-family:Verdana;font-size:85%;"  &gt;the service control manager (SCM) is asked to start a service, &lt;/span&gt;&lt;span style=";font-family:Verdana;font-size:85%;"  &gt;through the &lt;/span&gt;&lt;a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dllproc/base/startservice.asp"&gt;&lt;span style=";font-family:Verdana;font-size:85%;"  &gt;StartService&lt;/span&gt;&lt;/a&gt;&lt;span style=";font-family:Verdana;font-size:85%;"  &gt; function, it starts the process using the &lt;/span&gt;&lt;a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dllproc/base/createprocess.asp"&gt;&lt;span style=";font-family:Verdana;font-size:85%;"  &gt;CreateProcess&lt;/span&gt;&lt;/a&gt;&lt;span style=";font-family:Verdana;font-size:85%;"  &gt; function, it will go into the int WinMain(int nShowCmd) throw() inside the class.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;   int WinMain(int nShowCmd) throw()&lt;br /&gt;   {&lt;br /&gt;       if (CAtlBaseModule::m_bInitFailed)&lt;br /&gt;       {&lt;br /&gt;           ATLASSERT(0);&lt;br /&gt;           return -1;&lt;br /&gt;       }&lt;br /&gt;&lt;br /&gt;       T* pT = static_cast&lt;t*&gt;(this);&lt;br /&gt;       HRESULT hr = S_OK;&lt;br /&gt;&lt;br /&gt;       LPTSTR lpCmdLine = GetCommandLine();&lt;br /&gt;       if (pT-&gt;ParseCommandLine(lpCmdLine, &amp;hr) == true)&lt;br /&gt;           hr = pT-&gt;Start(nShowCmd);&lt;br /&gt;&lt;br /&gt;#ifdef _DEBUG&lt;br /&gt;       // Prevent false memory leak reporting. ~CAtlWinModule may be too late.&lt;br /&gt;       _AtlWinModule.Term();      &lt;br /&gt;#endif    // _DEBUG&lt;br /&gt;       return hr;&lt;br /&gt;   }&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;This function is called by the main thread in the process, no additional thread is created yet. This function will in turn call the Start() function.&lt;br /&gt;&lt;br /&gt;Inside the start function, it starts to hook up the real windows service stuff here, by checking the registery,&lt;br /&gt;&lt;br /&gt;       TCHAR szValue[MAX_PATH];&lt;br /&gt;       DWORD dwLen = MAX_PATH;&lt;br /&gt;       lRes = key.QueryStringValue(_T("LocalService"), szValue, &amp;dwLen);&lt;br /&gt;&lt;br /&gt;It will decide whether this is a service. [ In debug build, this won't be compiled and registered as  a service to make life easier to do the debug.]  If this is registered as a service, then a service table is created and StartServiceCtrlDispatcher is called to connect this service to the SCM.&lt;br /&gt;&lt;br /&gt;           SERVICE_TABLE_ENTRY st[] =&lt;br /&gt;           {&lt;br /&gt;               { m_szServiceName, _ServiceMain },&lt;br /&gt;               { NULL, NULL }&lt;br /&gt;           };&lt;br /&gt;           if (::StartServiceCtrlDispatcher(st) == 0)&lt;br /&gt;               m_status.dwWin32ExitCode = GetLastError();&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;StartServiceCtrlDispatcher &lt;/span&gt; &lt;span style=";font-family:Verdana;font-size:85%;"  &gt;establishes a connection that the SCM can use to send control commands to the service. StartServiceCtrlDispatcher will not return until the service has indicated that it has stopped. Once the connection to the SCM is established, StartServiceCtrlDispatcher creates a &lt;span style="color: rgb(255, 0, 0);"&gt;secondary thread&lt;/span&gt; that is the real starting point for the service. The second thread in this case is a static function called &lt;/span&gt;_ServiceMain, which in turn forwards the call to real ServiceMain function.&lt;br /&gt;&lt;br /&gt;[MSDN:&lt;br /&gt;&lt;br /&gt;&lt;/t*&gt;&lt;/t&gt;&lt;/class&gt;&lt;p&gt;When the service control manager starts a service process, it waits for the  process to call the &lt;b&gt;StartServiceCtrlDispatcher&lt;/b&gt; function. The main thread  of a service process should make this call as soon as possible after it starts  up. If &lt;b&gt;StartServiceCtrlDispatcher&lt;/b&gt; succeeds, it connects the calling  thread to the service control manager and does not return until all running  services in the process have terminated. The service control manager uses this  connection to send control and service start requests to the main thread of the  service process. &lt;span style="color: rgb(255, 0, 0);"&gt;The main thread&lt;/span&gt; acts as a dispatcher by invoking the  appropriate &lt;a href="handlerex.htm"&gt;&lt;b&gt;HandlerEx&lt;/b&gt;&lt;/a&gt; function to handle  control requests, or by creating a new thread to execute the appropriate &lt;a href="servicemain.htm"&gt;&lt;b&gt;ServiceMain&lt;/b&gt;&lt;/a&gt; function when a new service is  started.&lt;/p&gt;&lt;class&gt;&lt;t&gt;&lt;t*&gt;]&lt;br /&gt;&lt;br /&gt;The thread ServiceMain run is NOT the main thread referred here, the main thread is the controlling thread.&lt;br /&gt;&lt;br /&gt;   static void WINAPI _ServiceMain(DWORD dwArgc, LPTSTR* lpszArgv) throw()&lt;br /&gt;   {&lt;br /&gt;       ((T*)_pAtlModule)-&gt;ServiceMain(dwArgc, lpszArgv);&lt;br /&gt;   }&lt;br /&gt;&lt;br /&gt;The real ServiceMain is here:&lt;br /&gt;&lt;br /&gt;   void ServiceMain(DWORD dwArgc, LPTSTR* lpszArgv) throw()&lt;br /&gt;   {&lt;br /&gt;       lpszArgv;&lt;br /&gt;       dwArgc;&lt;br /&gt;       // Register the control request handler&lt;br /&gt;       m_status.dwCurrentState = SERVICE_START_PENDING;&lt;br /&gt;       m_hServiceStatus = RegisterServiceCtrlHandler(m_szServiceName, _Handler);&lt;br /&gt;       if (m_hServiceStatus == NULL)&lt;br /&gt;       {&lt;br /&gt;           LogEvent(_T("Handler not installed"));&lt;br /&gt;           return;&lt;br /&gt;       }&lt;br /&gt;       SetServiceStatus(SERVICE_START_PENDING);&lt;br /&gt;&lt;br /&gt;       m_status.dwWin32ExitCode = S_OK;&lt;br /&gt;       m_status.dwCheckPoint = 0;&lt;br /&gt;       m_status.dwWaitHint = 0;&lt;br /&gt;&lt;br /&gt;       T* pT = static_cast&lt;t*&gt;(this);&lt;br /&gt;#ifndef _ATL_NO_COM_SUPPORT&lt;br /&gt;&lt;br /&gt;       HRESULT hr = E_FAIL;&lt;br /&gt;       hr = T::InitializeCom();&lt;br /&gt;       if (FAILED(hr))&lt;br /&gt;       {&lt;br /&gt;           // Ignore RPC_E_CHANGED_MODE if CLR is loaded. Error is due to CLR initializing&lt;br /&gt;           // COM and InitializeCOM trying to initialize COM with different flags.&lt;br /&gt;           if (hr != RPC_E_CHANGED_MODE || GetModuleHandle(_T("Mscoree.dll")) == NULL)&lt;br /&gt;           {&lt;br /&gt;               return;&lt;br /&gt;           }&lt;br /&gt;       }&lt;br /&gt;       else&lt;br /&gt;       {&lt;br /&gt;           m_bComInitialized = true;&lt;br /&gt;       }&lt;br /&gt;&lt;br /&gt;       m_bDelayShutdown = false;&lt;br /&gt;#endif //_ATL_NO_COM_SUPPORT&lt;br /&gt;       // When the Run function returns, the service has stopped.&lt;br /&gt;       m_status.dwWin32ExitCode = pT-&gt;Run(SW_HIDE);&lt;br /&gt;&lt;br /&gt;#ifndef _ATL_NO_COM_SUPPORT&lt;br /&gt;       if (m_bService &amp;&amp;amp;amp; m_bComInitialized)&lt;br /&gt;           T::UninitializeCom();&lt;br /&gt;#endif&lt;br /&gt;&lt;br /&gt;       SetServiceStatus(SERVICE_STOPPED);&lt;br /&gt;       LogEvent(_T("Service stopped"));&lt;br /&gt;   }&lt;br /&gt;&lt;br /&gt;The first thing in service is to call  RegisterServiceCtrlHandler &lt;span style=";font-family:Verdana;font-size:85%;"  &gt;to register a callback function that the control dispatcher, inside StartServiceCtrlDispatcher, can use to pass control requests to the service. &lt;/span&gt;&lt;span style=";font-family:Verdana;font-size:85%;"  &gt;RegisterServiceCtrlHandler also returns a handle that is used in calls to the &lt;/span&gt;&lt;a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dllproc/base/setservicestatus.asp"&gt;&lt;span style=";font-family:Verdana;font-size:85%;"  &gt;SetServiceStatus&lt;/span&gt;&lt;/a&gt;&lt;span style=";font-family:Verdana;font-size:85%;"  &gt; function to update the SCM’s status information about the service.&lt;/span&gt;&lt;/t*&gt;&lt;/t*&gt;&lt;/t&gt;&lt;/class&gt; &lt;div class="tags"&gt;GISResearch&lt;ul&gt;&lt;li&gt;&lt;a href="http://del.icio.us/GISResearch/GISResearch+Programming." rel="tag"&gt;Programming.&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7462882-114571377269927332?l=gisresearch.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gisresearch.blogspot.com/feeds/114571377269927332/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7462882&amp;postID=114571377269927332' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7462882/posts/default/114571377269927332'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7462882/posts/default/114571377269927332'/><link rel='alternate' type='text/html' href='http://gisresearch.blogspot.com/2006/04/how-atl-supports-windows-service.html' title='How ATL supports windows service.'/><author><name>J.W.</name><uri>http://www.blogger.com/profile/09241601264454722977</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://farm3.static.flickr.com/2116/1856041089_20ef060d43_o.jpg'/></author><thr:total>0</thr:total></entry></feed>
