<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet href="http://feeds.feedburner.com/~d/styles/atom10full.xsl" type="text/xsl" media="screen"?><?xml-stylesheet href="http://feeds.feedburner.com/~d/styles/itemcontent.css" type="text/css" media="screen"?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:openSearch="http://a9.com/-/spec/opensearchrss/1.0/" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0"><id>tag:blogger.com,1999:blog-16787577</id><updated>2008-01-31T06:30:53.167-05:00</updated><title type="text">Joe's Blog</title><link rel="alternate" type="text/html" href="http://jebsoft.blogspot.com/" /><link rel="http://schemas.google.com/g/2005#feed" type="application/atom+xml" href="http://jebsoft.blogspot.com/feeds/posts/default" /><author><name>Joe</name><uri>http://www.blogger.com/profile/09934847924862941566</uri><email>noreply@blogger.com</email></author><generator version="7.00" uri="http://www.blogger.com">Blogger</generator><openSearch:totalResults>10</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><geo:lat>35.899208</geo:lat><geo:long>-78.711619</geo:long><link rel="self" href="http://feeds.feedburner.com/blogspot/jebsoft" type="application/atom+xml" /><feedburner:browserFriendly>This is an XML content feed. It is intended to be viewed in a newsreader or syndicated to another site, subject to copyright and fair use.</feedburner:browserFriendly><entry><id>tag:blogger.com,1999:blog-16787577.post-115812212237757470</id><published>2006-09-12T23:32:00.001-05:00</published><updated>2006-09-12T23:38:01.760-05:00</updated><title type="text">New Blog</title><content type="html">Blogging is getting better.  I have been less than prolific in my blogging, partly because I have almost no time and partly because it just wasn't much fun.  That last part seems to be changing with newer tools that make things easier and quicker.  I have decided to try other blogware (you can see it &lt;a href="http://idevelopwith.spaces.live.com/"&gt;here&lt;/a&gt;) to take advantage of new features and technology.  I'll see how I like it after using it for a while.</content><link rel="alternate" type="text/html" href="http://jebsoft.blogspot.com/2006/09/new-blog_13.html" title="New Blog" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=16787577&amp;postID=115812212237757470" title="0 Comments" /><link rel="replies" type="application/atom+xml" href="http://jebsoft.blogspot.com/feeds/115812212237757470/comments/default" title="Post Comments" /><link rel="self" type="application/atom+xml" href="http://jebsoft.blogspot.com/feeds/posts/default/115812212237757470" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/16787577/posts/default/115812212237757470" /><author><name>Joe</name><uri>http://www.blogger.com/profile/09934847924862941566</uri><email>noreply@blogger.com</email></author></entry><entry><id>tag:blogger.com,1999:blog-16787577.post-115445468405834731</id><published>2006-08-01T12:22:00.000-05:00</published><updated>2006-08-01T12:57:39.710-05:00</updated><title type="text">Another Simple Thing</title><content type="html">Sometimes I can get a little long-winded when naming variables or methods. Combine that with a secret desire to write a complete program with one line of code and you can imagine what my code can look like if I don’t exercise a little constraint. With that in mind, I came across this little trick to add vertical guidelines in my editor window. They serve as a reminder that my lines shouldn’t get too long. I have seen this trick before, and actually used it at one time, but forgot about it until recently. Here is what it looks like. Notice the vertical red lines in the editor window.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://photos1.blogger.com/blogger/5577/286/1600/editor.0.gif"&gt;&lt;img style="CURSOR: hand" alt="" src="http://photos1.blogger.com/blogger/5577/286/400/editor.png" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Ok, how do we get there from here? Crank up Regedit.exe and get ready for some registry surgery (insert the usual warnings about the possible dire consequences of registry editing, etc. here).&lt;br /&gt;&lt;br /&gt;Go to HKEY_CURRENT_USER\Software\Microsoft\VisualStudio\&amp;lt;your version number (7.1, 8.0, etc.)&amp;gt;\Text Editor and add a new string named “Guides” with the following value: RGB(r,g,b) gl1 gl2 … where r, g, and b are the values (0 .. 255) of the color you want for your guide lines. gl1, gl2, etc. are the column number where you want your guide lines to appear. My guidelines are light red and are located at columns 80 and 110. My registry entry is shown below.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://photos1.blogger.com/blogger/5577/286/1600/registry.gif"&gt;&lt;img style="CURSOR: hand" alt="" src="http://photos1.blogger.com/blogger/5577/286/400/registry.png" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Enjoy, and keep those lines of code short enough to be readable.</content><link rel="alternate" type="text/html" href="http://jebsoft.blogspot.com/2006/08/another-simple-thing.html" title="Another Simple Thing" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=16787577&amp;postID=115445468405834731" title="0 Comments" /><link rel="replies" type="application/atom+xml" href="http://jebsoft.blogspot.com/feeds/115445468405834731/comments/default" title="Post Comments" /><link rel="self" type="application/atom+xml" href="http://jebsoft.blogspot.com/feeds/posts/default/115445468405834731" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/16787577/posts/default/115445468405834731" /><author><name>Joe</name><uri>http://www.blogger.com/profile/09934847924862941566</uri><email>noreply@blogger.com</email></author></entry><entry><id>tag:blogger.com,1999:blog-16787577.post-115444949407592610</id><published>2006-08-01T11:22:00.000-05:00</published><updated>2006-08-01T11:27:41.493-05:00</updated><title type="text">It’s the Simple Things</title><content type="html">You have to love the simple things that save time and make your life easier.  Years ago, back in the days of DOS, I used an editor named Brief.  Brief was published by a company named UnderWare and was later acquired by Borland.  Borland still has Brief emulation in their editors and so do other publishers.  One of the things I liked about Brief and missed in the Visual Studio IDE editor is the ability to select columns of text.  It’s the little things I miss when they aren’t available.&lt;br /&gt;&lt;br /&gt;One day while editing some code in Visual Studio I accidently selected columns of text.  I didn’t know what I had done to cause the column selection but set out on a search for the magic keystroke combination that would duplicate my fat-fingering and bring column selection home to me.  After a little trial and error, I discovered that like holding down the shift key while moving the cursor to select rows of text, if I add the Alt key to that combination I can select columns.  Interestingly, you have to use Alt-Shift with the arrow keys to select columns with the keyboard, but just Alt will do if you select columns by holding down the left mouse button and dragging the mouse.  Don’t ask me why it works like that; it does and I’m loving it.</content><link rel="alternate" type="text/html" href="http://jebsoft.blogspot.com/2006/08/its-simple-things.html" title="It’s the Simple Things" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=16787577&amp;postID=115444949407592610" title="0 Comments" /><link rel="replies" type="application/atom+xml" href="http://jebsoft.blogspot.com/feeds/115444949407592610/comments/default" title="Post Comments" /><link rel="self" type="application/atom+xml" href="http://jebsoft.blogspot.com/feeds/posts/default/115444949407592610" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/16787577/posts/default/115444949407592610" /><author><name>Joe</name><uri>http://www.blogger.com/profile/09934847924862941566</uri><email>noreply@blogger.com</email></author></entry><entry><id>tag:blogger.com,1999:blog-16787577.post-115292638570974319</id><published>2006-07-14T20:19:00.000-05:00</published><updated>2006-07-16T08:44:04.290-05:00</updated><title type="text">Creating a Strongly Typed Heterogeneous Collection in .NET 2.0.</title><content type="html">&lt;span style="font-family:Verdana;"&gt;I found a solution to an interesting problem while developing an application for a state licensing board. I was using generics for strongly-typed collections of objects, but had a need to have collections of several types of objects that are historical events for a person. In this case, as a person goes through the process of becoming licensed, applications are required for exams, different exams must be taken and passed, and other requirements must be met before licensing can be completed. The historical events don’t end there though. Continuing education requirements must be maintained, complaints might be filed against the licensee, the license may become inactive and later reinstated, or a number of other events could occur. I wanted to be able to maintain a history for each person from first application through licensing and beyond. My first thought was to just maintain collections for each type of historical event. It soon became obvious I would have many collections to manage, so another solution seemed necessary. &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Verdana;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Verdana;"&gt;After thinking about several approaches, I decided to make a base class named HistoryItem and all of the historical events now derive from it. If you are thinking these items are not related you are partially correct. A license is not a complaint and a complaint is not a license, so there isn’t an “is-a” relationship. A license doesn’t have a complaint and a complaint doesn’t have a license, so there isn’t a “has-a” relationship either. The same can be said about the other historical items and events. Normally we would say the items are not at all related. But, they are historical items or events for a particular person. In other words, they are related because we want to treat them the same way, as historical items. With this approach all the history can be stored in a single collection which will be much easier to manage.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Verdana;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Verdana;"&gt;Feeling proud of myself for solving this problem, I turned my attention to manipulating the collections and ran into the reason we usually don’t store different kinds of things in the same collection. How could I compare two items in the collection when they could be different types? I could see the algorithm starting to take shape. If the first item is this type and the second item is that type do something, but if the first item is that type and the second is this type, then do something else, but if they are both the same type then compare some properties to see if they are equal or not. Well, the algorithm is as ugly as that description. Another solution seemed necessary.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Verdana;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Verdana;"&gt;I decided comparers would be a big help, so I developed a set of classes that implemented the IComparer interface. If you aren’t familiar with that interface, it has one method named Compare. Compare takes two arguments and since I was using generic collections I wanted strongly typed comparers. Both arguments are HistoryItems. Now I can compare items in my collection, and search for a particular item I might find interesting. But wait, how do I know which comparer to use? I could see the algorithm taking shape. If I’m interested in this type use this comparer, but if I’m interested in that type use that comparer. Once again I was faced with an ugly algorithm and another solution seemed necessary.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Verdana;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Verdana;"&gt;What I really wanted was some mechanism that could give me the comparer I needed to use. Fortunately, that is what a factory does. But, a factory needs some information so it can make a decision about what kind of thing to create. I decided to hand my ComparerFactory the HistoryItem currently of interest and ask the factory to provide a comparer I can use with that item. I could see the factory algorithm starting to take shape. If I get this type then create this comparer, but if I get that type then create that comparer, or if I get the other type then create the other comparer. That sounded like another ugly algorithm. It could get even uglier if several new types of items and comparers were developed, so another solution seemed necessary.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Verdana;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Verdana;"&gt;If my factory could create any type without knowing anything about the type it was creating all my problems would be solved. I decided my solution should not depend on the type of the item I need to compare, but my item should be able to tell the factory what type of comparer to create. I decided to create a custom attribute that could decorate my items and the factory could use reflection to learn what type of comparer to create. Here is my attribute and how to apply it to a class.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Consolas;font-size:85%;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;span style="font-family:Consolas;font-size:85%;"&gt;[AttributeUsage(AttributeTargets.Class,&lt;br&gt;AllowMultiple = false, Inherited = false)]&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Consolas;font-size:85%;"&gt;public class CompatibleComparerAttribute : System.Attribute&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Consolas;font-size:85%;"&gt;{&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Consolas;font-size:85%;"&gt;    private string _comparerName;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Consolas;font-size:85%;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Consolas;font-size:85%;"&gt;    public string ComparerName&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Consolas;font-size:85%;"&gt;    {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Consolas;font-size:85%;"&gt;        get { return _comparerName; }&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Consolas;font-size:85%;"&gt;    }&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Consolas;font-size:85%;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Consolas;font-size:85%;"&gt;    public CompatibleComparerAttribute(string comparerName)&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Consolas;font-size:85%;"&gt;    {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Consolas;font-size:85%;"&gt;        _comparerName = comparerName;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Consolas;font-size:85%;"&gt;    }&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Consolas;font-size:85%;"&gt;}&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;&lt;span style="font-family:Verdana;font-size:85%;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Verdana;"&gt;Now apply it to a class.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Verdana;font-size:85%;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Consolas;font-size:85%;"&gt;[CompatibleComparer(“ApplicationComparer”)]&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Consolas;font-size:85%;"&gt;public class Application : HistoryItem&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Consolas;font-size:85%;"&gt;{&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Consolas;font-size:85%;"&gt;. . .&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Consolas;font-size:85%;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Verdana;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Verdana;"&gt;Now, my factory knows what type of comparer to create. I can see the algorithm starting to take shape. If I need to create a “ApplicationComparer” then create an instance of ApplicationComparer, but if I need to create a “ThisComparer”, then create an instance of ThisComparer, or if I need to create a “ThatComparer” then create an instance of ThatComparer. My algorithm is as ugly as ever and another solution seems necessary.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Verdana;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;strong&gt;&lt;span style="font-family:Verdana;"&gt;The Solution – Putting It All Together&lt;/span&gt;&lt;/strong&gt;&lt;br /&gt;&lt;span style="font-family:Verdana;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Verdana;"&gt;The System.Runtime.Remoting namespace contains a nifty little class named Activator. If you haven’t used it before check it out, it’s very useful. It can create an instance of a class if it knows its full namespace and class name. So, I just need to pass the Activator “FullNameSpace.ClassName” and it will create an instance for me. Putting it all together, I am using a strongly-typed generic collection so I can treat all my HistoryItem instances the same. Each class derived from HistoryItem is decorated with my custom attribute that contains the full namespace and class name for the comparer to use. My factory can use reflection to discover what to create with the Activator. Now, my code looks similar to this:&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Verdana;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Consolas;font-size:85%;"&gt;History history = new History();&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Consolas;font-size:85%;"&gt;. . .&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Consolas;font-size:85%;"&gt;HistoryItem item = new License();&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Consolas;font-size:85%;"&gt;History.Add(item);&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Consolas;font-size:85%;"&gt;. . .&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Consolas;font-size:85%;"&gt;IComparer&amp;lt;HistoryItem&amp;gt; comparer = ComparerFactory.CreateComparer(item);&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Consolas;font-size:85%;"&gt;int index = history.IndexOf(item, comparer);&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Verdana;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Verdana;"&gt;The factory code itself is very short; this is the only method.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Verdana;"&gt;&lt;/span&gt;&lt;pre&gt;&lt;br /&gt;&lt;span style="font-family:Consolas;font-size:85%;"&gt;public static IComparer&amp;lt;HistoryItem&amp;gt; CreateComparer(HistoryItem item)&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Consolas;font-size:85%;"&gt;{&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Consolas;font-size:85%;"&gt;    object[] attrs = item.GetType().GetCustomAttributes(&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Consolas;font-size:85%;"&gt;&lt;br&gt;        typeof(CompatibleComparerAttribute), false);&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Consolas;font-size:85%;"&gt;    if (attrs.Length == 0)&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Consolas;font-size:85%;"&gt;    {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Consolas;font-size:85%;"&gt;        return null;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Consolas;font-size:85%;"&gt;    }&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Consolas;font-size:85%;"&gt;    CompatibleComparerAttribute attr = &lt;br&gt;        attrs[0] as CompatibleComparerAttribute;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Consolas;font-size:85%;"&gt;    ObjectHandle objHandle = &lt;br&gt;        Activator.CreateInstance(null, attr.ComparerName);&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Consolas;font-size:85%;"&gt;    return objHandle.Unwrap() as IComparer&amp;lt;HistoryItem&amp;gt;;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Consolas;font-size:85%;"&gt;}&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;&lt;span style="font-family:Verdana;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Verdana;"&gt;Now my code is not ugly, and can handle new HistoryItems and comparers in the future. I’m happy and life is good. The .NET library came through with a solution that is simple and can be easily maintained.&lt;/span&gt;</content><link rel="alternate" type="text/html" href="http://jebsoft.blogspot.com/2006/07/creating-strongly-typed-heterogeneous.html" title="Creating a Strongly Typed Heterogeneous Collection in .NET 2.0." /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=16787577&amp;postID=115292638570974319" title="0 Comments" /><link rel="replies" type="application/atom+xml" href="http://jebsoft.blogspot.com/feeds/115292638570974319/comments/default" title="Post Comments" /><link rel="self" type="application/atom+xml" href="http://jebsoft.blogspot.com/feeds/posts/default/115292638570974319" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/16787577/posts/default/115292638570974319" /><author><name>Joe</name><uri>http://www.blogger.com/profile/09934847924862941566</uri><email>noreply@blogger.com</email></author></entry><entry><id>tag:blogger.com,1999:blog-16787577.post-115041887838677776</id><published>2006-06-15T19:47:00.000-05:00</published><updated>2006-06-15T20:00:55.843-05:00</updated><title type="text">Pro .NET 2.0 Code and Design Standards in C#</title><content type="html">Mark Horner takes on the ambitious project of telling us how to standardize code, design, and patterns in &lt;a href="http://www.amazon.com/gp/product/1590595602/sr=8-1/qid=1150418807/ref=pd_bbs_1/103-9922030-0687842?%5Fencoding=UTF8" target="_blank"&gt;“Pro .NET 2.0 Code and Design Standards in C#”&lt;/a&gt; published by Apress.&amp;nbsp;&amp;nbsp;A what, where, why and how format for each topic promised the reasoning and justification for the standard practices.&amp;nbsp;&amp;nbsp;I had high expectations for a clear explanation of a proposed standard for designing and developing applications in C#.&amp;nbsp;&amp;nbsp;This book misses the mark and left me wondering what standard was being proposed.&lt;br/&gt;&lt;br/&gt;As I read through the book, I kept wondering why the material I had just read was included in the book.&amp;nbsp;&amp;nbsp;For example, in a book about C# standards the author discusses Visual Basic naming conventions, and even demonstrates the use of a leading underscore for a variable name with Visual Basic code.&amp;nbsp;&amp;nbsp;The author makes confusing claims such as “…there is always an option to accept a .NET standard, which rules against using case sensitivity (e.g. in C# language).”&amp;nbsp;&amp;nbsp;The syntax of basic language structures is covered, such as an if statement, including the optional else clause.&lt;br/&gt;&lt;br/&gt;The what, where, why and how format of each topic is followed by an acknowledgement of the practice.&amp;nbsp;&amp;nbsp;Apparently believing the first acknowledgement isn’t enough, a List of Standards is included in the back of the book where the acknowledgements are repeated.&lt;br/&gt;&lt;br/&gt;The purpose of the book seems to be mentioning as many topics as possible, whether or not they have anything to do with standards.&amp;nbsp;&amp;nbsp;For instance, the author felt the need to include the first 128 ASCII characters and parentheses in the glossary but not tell you their purpose.&amp;nbsp;&amp;nbsp;The entire entry for parentheses is&lt;br/&gt;()&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Parentheses.&lt;br/&gt;&lt;br/&gt;Compare that to the much more enlightening &lt;br/&gt;‘&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Single quote – not a comment (“//” or “/*…*/”).&lt;br/&gt;&lt;br/&gt;The weight given topics seems strange as well, with the if statement getting about the same coverage as service oriented architecture, about two pages each.&amp;nbsp;&amp;nbsp;Based on the title, I expected to see a standard developed.&amp;nbsp;&amp;nbsp;What a surprise.&amp;nbsp;&amp;nbsp;At the end of the day what we are left with is not a standard at all, but just acknowledgements that various things exist.&amp;nbsp;&amp;nbsp;&lt;br/&gt;&lt;br/&gt;Maybe I’ve just had my expectations set too high by the excellent “Framework Design Guidelines” by Krzysztof Cwalina and Brad Abrams, but Horner’s book is a big disappointment.&amp;nbsp;&amp;nbsp;Save your money.</content><link rel="alternate" type="text/html" href="http://jebsoft.blogspot.com/2006/06/pro-net-20-code-and-design-standards.html" title="Pro .NET 2.0 Code and Design Standards in C#" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=16787577&amp;postID=115041887838677776" title="1 Comments" /><link rel="replies" type="application/atom+xml" href="http://jebsoft.blogspot.com/feeds/115041887838677776/comments/default" title="Post Comments" /><link rel="self" type="application/atom+xml" href="http://jebsoft.blogspot.com/feeds/posts/default/115041887838677776" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/16787577/posts/default/115041887838677776" /><author><name>Joe</name><uri>http://www.blogger.com/profile/09934847924862941566</uri><email>noreply@blogger.com</email></author></entry><entry><id>tag:blogger.com,1999:blog-16787577.post-114437792888267905</id><published>2006-04-06T21:39:00.000-05:00</published><updated>2006-04-06T22:34:11.083-05:00</updated><title type="text">Consistent Version Numbers Across All Assemblies</title><content type="html">I came across a simple, but useful, technique the other day. It keeps the version numbers of all assemblies consistent when building your Visual Studio solution. It works with either 2003 or 2005 flavors. I’ll describe the C# 2005 version since I have it installed on my machine, but 2003 works the same way.&lt;br /&gt;&lt;br /&gt;Have you ever looked at what’s inside AssemblyInfo.cs? Go ahead and take a look; there is one in each project. There are a few using directives at the top, and the rest of the file contains assembly level attributes. Some of them will vary from assembly to assembly, such as AssemblyTitle and AssemblyDescription. Some of the others will be the same from one project to another in the same solution. These are “solution level” attributes. AssemblyCompany and AssemblyCopyright are examples of attributes that probably should be solution level attributes. AssemblyVersion is also one of the attributes included in the file. We will work with it in just a bit.&lt;br /&gt;&lt;br /&gt;The first task is to take a look at the attributes already in the file and any additional attributes you want to add, and decide which ones are specific to a particular assembly and which ones should be solution level. Now add a new file called SolutionInfo.cs to the solution. A new folder named Solution Items will be created under the solution and SolutionInfo.cs will be in the folder. Copy all the solution level attributes into it and remove them from all the AssemblyInfo.cs files. For example, copy the AssemblyCompany attribute to the SolutionInfo.cs file and delete it from the AssemblyInfo.cs file for each project in the solution. There should be no overlap of attributes between AssemblyInfo.cs and SolutionInfo.cs. If the same attribute appears in both file, you will probably get a compile error.&lt;br /&gt;&lt;br /&gt;We now have a reduced set of the attributes in each project and the remainder of the attributes in the Solution Items folder. What we need is to have all the attributes from the SolutionInfo.cs file in each project. If we add the SolutionInfo.cs file to each project we are right back where we started and haven’t really accomplished anything. What we really need, is the contents of the SolutionInfo.cs file in each project without the actual file. It turns out there is an easy way to do just that.&lt;br /&gt;&lt;br /&gt;For each project, add an existing item and navigate to the folder containing SolutionInfo.cs.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://photos1.blogger.com/blogger/5577/286/1600/AddArrow.0.jpg"&gt;&lt;img style="DISPLAY: block; MARGIN: 0px auto 10px; CURSOR: hand; TEXT-ALIGN: center" alt="" src="http://photos1.blogger.com/blogger/5577/286/400/AddArrow.jpg" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Instead of double-clicking the file or clicking on the Add button, use the little arrow to the right of the Add button to drop down a list of options. Select Add As Link from the drop down list. That adds the following entry to your project files.&lt;br /&gt;&lt;code&gt;&lt;pre&gt;&lt;br /&gt;&amp;lt;Compile Include="..\SolutionInfo.cs"&amp;gt&lt;br /&gt;    &amp;lt;Link&amp;gt;SolutionInfo.cs&amp;lt;/Link&amp;gt;&lt;br /&gt;&amp;lt;/Compile&amp;gt;;&lt;/pre&gt;&lt;/code&gt;&lt;br /&gt;The compiler will include that file when it compiles each project, but the physical file is in just one location. Make sure the AssemblyVersion attribute is in the SolutionInfo.cs file and not in the AssemblyInfo.cs file in each project. If your application is at version 1.0 and you want to increase the version number to 1.1, just change it in the SolutionInfo.cs file and as each project is compiled, the version number is set to 1.1.&lt;br /&gt;&lt;br /&gt;Try it, I think you will like it.</content><link rel="alternate" type="text/html" href="http://jebsoft.blogspot.com/2006/04/consistent-version-numbers-across-all.html" title="Consistent Version Numbers Across All Assemblies" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=16787577&amp;postID=114437792888267905" title="1 Comments" /><link rel="replies" type="application/atom+xml" href="http://jebsoft.blogspot.com/feeds/114437792888267905/comments/default" title="Post Comments" /><link rel="self" type="application/atom+xml" href="http://jebsoft.blogspot.com/feeds/posts/default/114437792888267905" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/16787577/posts/default/114437792888267905" /><author><name>Joe</name><uri>http://www.blogger.com/profile/09934847924862941566</uri><email>noreply@blogger.com</email></author></entry><entry><id>tag:blogger.com,1999:blog-16787577.post-114238844032957837</id><published>2006-03-14T21:07:00.000-05:00</published><updated>2006-03-16T13:20:52.593-05:00</updated><title type="text">Framework Design Guidelines</title><content type="html">A couple of weeks ago I found a book on Amazon that looked interesting.&amp;nbsp;&amp;nbsp;“&lt;a href="http://www.amazon.com/gp/product/0321246756/104-9204962-7211164?v=glance&amp;n=283155" target="_blank"&gt;Framework Design Guidelines&lt;/a&gt;” by &lt;a href="http://blogs.msdn.com/kcwalina/" target="_blank"&gt;Krzysztof Cwalina&lt;/a&gt; and &lt;a href="http://blogs.msdn.com/brada/" target="_blank"&gt;Brad Abrams&lt;/a&gt; is part of the Microsoft .NET Development Series.&amp;nbsp;&amp;nbsp;The authors have been involved in the design and development of the CLR and .NET Framework since the beginning and the experience and insight of those years comes through in a style that is easy to read.&amp;nbsp;&amp;nbsp;This is not a book about .NET technology or how to program the latest features .NET has to offer.&amp;nbsp;&amp;nbsp;It is about best practices when developing libraries of code.&amp;nbsp;&amp;nbsp;&lt;br/&gt;&lt;br/&gt;Sprinkled throughout the pages are comments by Brad and Krzysztof, Paul Vick, Anders Hejlsberg, Rico Mariani, Brent Rector, Chris Anderson, Jeffrey Richter, and others that give an almost conversational feel to the topics.&amp;nbsp;&amp;nbsp;You can almost imagine yourself sitting around with a bunch of Microsoft architects discussing the pros and cons of naming conventions, the contents of namespaces, what makes a library easy to use and reusable, factoring high-level and low-level APIs, requirements and goals, and a host of other topics.&amp;nbsp;&amp;nbsp;If you have experience with .NET, their discussions sound immediately familiar and the insight of why choices were made and compromises reached gives you an understanding of what a huge undertaking it was to develop the framework.&amp;nbsp;&amp;nbsp;They really made an effort to get the framework right, and throughout the book they discuss their successes and the areas where they fell short.&lt;br/&gt;&lt;br/&gt;The guidance is presented as a set of recommendations using &lt;strong&gt;Do&lt;/strong&gt;, &lt;strong&gt;Consider&lt;/strong&gt;, &lt;strong&gt;Avoid&lt;/strong&gt;, and &lt;strong&gt;Do Not&lt;/strong&gt;.&amp;nbsp;&amp;nbsp;&lt;strong&gt;Do &lt;/strong&gt;means always follow the guidance unless you have a really unusual case; &lt;strong&gt;Consider &lt;/strong&gt;is for guidance you would usually want to follow; &lt;strong&gt;Avoid &lt;/strong&gt;is for things that are generally not a good idea; and &lt;strong&gt;Do Not &lt;/strong&gt;is reserved for those things that should almost never be done.&amp;nbsp;&amp;nbsp;Along with the recommendations are explanations of why they are good or bad practices.&lt;br/&gt;&lt;br/&gt;This book is packed with recommendations on all areas of framework design.&amp;nbsp;&amp;nbsp;Areas covered include Qualities of a Well-Designed Framework, Framework Design Fundamentals, Naming Guidelines, Type Design Guidelines, Member Design, Designing for Extensibility, Exceptions, Usage Guidelines, and Common Design Patterns, followed by three appendices on C# Coding Style Conventions, Using FxCop to Enforce Design Guidelines, and a Sample API Specification.&amp;nbsp;&amp;nbsp;Reading this book will make you a better framework designer and your libraries will be easier to use and more consistent.&amp;nbsp;&amp;nbsp;I highly recommend it for the information, insight into framework design, and being an enjoyable read.</content><link rel="alternate" type="text/html" href="http://jebsoft.blogspot.com/2006/03/framework-design-guidelines.html" title="Framework Design Guidelines" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=16787577&amp;postID=114238844032957837" title="0 Comments" /><link rel="replies" type="application/atom+xml" href="http://jebsoft.blogspot.com/feeds/114238844032957837/comments/default" title="Post Comments" /><link rel="self" type="application/atom+xml" href="http://jebsoft.blogspot.com/feeds/posts/default/114238844032957837" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/16787577/posts/default/114238844032957837" /><author><name>Joe</name><uri>http://www.blogger.com/profile/09934847924862941566</uri><email>noreply@blogger.com</email></author></entry><entry><id>tag:blogger.com,1999:blog-16787577.post-114057713818034447</id><published>2006-02-21T21:51:00.000-05:00</published><updated>2006-02-22T11:52:57.183-05:00</updated><title type="text">Enterprise Library Logging Application Block</title><content type="html">I’ve downloaded the January 2006 Enterprise Library and installed it. I wanted to play with the logging application block for some things I’ve got in mind. It’s very easy to configure and use the blocks. Included in the download is the Enterprise Library Configuration Utility. You open your app.config or web.config file with the utility and the necessary sections and entries are saved there for you.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://photos1.blogger.com/blogger/5577/286/1600/elcu.gif"&gt;&lt;img style="DISPLAY: block; MARGIN: 0px auto 10px; CURSOR: hand; TEXT-ALIGN: center" alt="" src="http://photos1.blogger.com/blogger/5577/286/400/elcu.jpg" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;TraceListeners provide a location for the logging data to be stored. For example, the FlatFile TraceListener uses a text file with a name of trace.log by default. Other TraceListeners are provided for database, MSMQ, email, and the Windows event log, just to name a few; and you can even create your own. Adding one of the TraceListeners to a Category sends log data for that category to the appropriate store. Once the configuration is complete, it’s time to write some logging code.&lt;br /&gt;&lt;br /&gt;Before writing the logging code there is one little bit of housekeeping that’s necessary. Add references to:&lt;br /&gt;Microsoft.Practices.EnterpriseLibrary.Common.dll&lt;br /&gt;Microsoft.Practices.EnterpriseLibrary.Logging.dll&lt;br /&gt;Microsoft.Practices.ObjectBuilder.dll&lt;br /&gt;&lt;br /&gt;Add the following at the top of your source file:&lt;br /&gt;using Microsoft.Practices.EnterpriseLibrary.Logging;&lt;br /&gt;using Microsoft.Practices.EnterpriseLibrary.Logging.ExtraInformation;&lt;br /&gt;using Microsoft.Practices.EnterpriseLibrary.Logging.Filters;&lt;br /&gt;&lt;br /&gt;Now, you are ready to write some code. The LogEntry class will contain the data that you want to log. So, create one, set some of its properties, and write it to the log.  Logger is a static class that contains a bunch of overloaded static Write methods.  It makes it all very easy.&lt;br /&gt;&lt;br /&gt;LogEntry logEntry = new LogEntry();&lt;br /&gt;logEntry.EventId = 100;&lt;br /&gt;logEntry.Categories.Add("Runtime Data Collection");&lt;br /&gt;logEntry.Priority = 6;&lt;br /&gt;logEntry.Severity = System.Diagnostics.TraceEventType.Critical;&lt;br /&gt;logEntry.Message = "Logging important information"; &lt;br /&gt;logEntry.Title = "Test Entry";&lt;br /&gt;logEntry.MachineName = Environment.MachineName;&lt;br /&gt;Logger.Write(logEntry);&lt;br /&gt;&lt;br /&gt;That’s really all there is to basic logging. Running the application in Visual Studio 2005 produces the following log entry.&lt;br /&gt;&lt;br /&gt;----------------------------------------&lt;br /&gt;Timestamp: 2/22/2006 2:40:45 AM&lt;br /&gt;Message: Logging important information&lt;br /&gt;Category: Runtime Data Collection&lt;br /&gt;Priority: 6&lt;br /&gt;EventId: 100&lt;br /&gt;Severity: Critical&lt;br /&gt;Title:Test Entry&lt;br /&gt;Machine: GODZILLA&lt;br /&gt;Application Domain: LoggingApp.vshost.exe&lt;br /&gt;Process Id: 4128&lt;br /&gt;Process Name: C:\Documents and Settings\jbennett\My Documents\Visual Studio 2005\Projects\LoggingApp\LoggingApp\bin\Debug\LoggingApp.vshost.exe&lt;br /&gt;Win32 Thread Id: 4144&lt;br /&gt;Thread Name: UI Thread&lt;br /&gt;Extended Properties:&lt;br /&gt;----------------------------------------&lt;br /&gt;&lt;br /&gt;Easy logging is only a download away.  Get it &lt;a href="http://msdn.microsoft.com/practices/" target="_blank"&gt;here&lt;/a&gt;.</content><link rel="alternate" type="text/html" href="http://jebsoft.blogspot.com/2006/02/enterprise-library-logging-application.html" title="Enterprise Library Logging Application Block" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=16787577&amp;postID=114057713818034447" title="2 Comments" /><link rel="replies" type="application/atom+xml" href="http://jebsoft.blogspot.com/feeds/114057713818034447/comments/default" title="Post Comments" /><link rel="self" type="application/atom+xml" href="http://jebsoft.blogspot.com/feeds/posts/default/114057713818034447" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/16787577/posts/default/114057713818034447" /><author><name>Joe</name><uri>http://www.blogger.com/profile/09934847924862941566</uri><email>noreply@blogger.com</email></author></entry><entry><id>tag:blogger.com,1999:blog-16787577.post-113945442308261195</id><published>2006-02-08T22:07:00.000-05:00</published><updated>2006-02-08T22:07:03.103-05:00</updated><title type="text">TRINUG Meeting</title><content type="html">Kate Gregory spoke at the TRINUG (&lt;a href="http://www.trinug.org/"&gt;www.trinug.org&lt;/a&gt;) meeting tonight.&amp;nbsp;&amp;nbsp;Her topic was Click-Once meets the real world.&amp;nbsp;&amp;nbsp;She talked about the capabilities of Click-Once using just the Visual Studio IDE, and how to get a little more juice out of the new deployment technology by writing just a little code.&amp;nbsp;&amp;nbsp;It’s very cool and worth investigating if you are interested in smart client applications.&lt;br/&gt;&lt;br/&gt;Next month at the TRINUG meeting will be The Hitchhikers Guide To Unintentionally Creating Mission Critical .Net Web-Services Applications ... And Some Intentional Solutions by Mark Sundt.&amp;nbsp;&amp;nbsp;If you live in the Triangle of North Carolina and don’t attend the TRINUG meetings, you are missing out on some very informative speakers.&amp;nbsp;&amp;nbsp;I’d encourage you to find out more at the website.</content><link rel="alternate" type="text/html" href="http://jebsoft.blogspot.com/2006/02/trinug-meeting.html" title="TRINUG Meeting" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=16787577&amp;postID=113945442308261195" title="1 Comments" /><link rel="replies" type="application/atom+xml" href="http://jebsoft.blogspot.com/feeds/113945442308261195/comments/default" title="Post Comments" /><link rel="self" type="application/atom+xml" href="http://jebsoft.blogspot.com/feeds/posts/default/113945442308261195" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/16787577/posts/default/113945442308261195" /><author><name>Joe</name><uri>http://www.blogger.com/profile/09934847924862941566</uri><email>noreply@blogger.com</email></author></entry><entry><id>tag:blogger.com,1999:blog-16787577.post-113733953920461250</id><published>2006-01-15T10:38:00.000-05:00</published><updated>2006-01-15T10:38:59.450-05:00</updated><title type="text">ClearCase Nightmares</title><content type="html">For those who don’t know, ClearCase is the IBM solution for source code management.&amp;nbsp;&amp;nbsp;I am using it on a project for a client and it has been a nightmare.&amp;nbsp;&amp;nbsp;It regularly corrupts source files and resource files.&amp;nbsp;&amp;nbsp;Getting everything working again can be challenging to say the least.&amp;nbsp;&amp;nbsp;I think the problem is the way ClearCase views files as a stream of characters.&amp;nbsp;&amp;nbsp;It has no concept of methods, properties, or other characteristics found in modern source code.&amp;nbsp;&amp;nbsp;That makes merges very interesting.&amp;nbsp;&amp;nbsp;It seems to get confused very easily and when that happens, what you get out of it can be just as confusing.&lt;br/&gt;&lt;br/&gt;It seems to follow this algorithm: Take random bytes from the file in the repository, and merge them in random and creative ways with random bytes from the corresponding file on your local drive.&amp;nbsp;&amp;nbsp;Repeat this process until the end of both files is reached to produce the final merged file for use in your project.&amp;nbsp;&amp;nbsp;As you can imagine, this produces some very interesting results that make the compiler frown and grumble about various things and puts you on the path of a day-long journey to sort out the whole mess.&amp;nbsp;&amp;nbsp;I wonder if IBM has a QA group for the software development teams…&lt;br/&gt;&lt;br/&gt;I’ve used several SCM products on various projects and they all seem to have their quirks and gotchas.&amp;nbsp;&amp;nbsp;I haven’t had that warm, fuzzy feeling of knowing my files are safe and secure, and what I put in will come back out in the same condition when I make changes.&amp;nbsp;&amp;nbsp;So, to end my rant, let me make a prediction.&amp;nbsp;&amp;nbsp;If Microsoft’s Team System contains a good, friendly, reliable, stable, source management system (and I haven’t used it, so I don’t know) it will dominate the market for source control.&amp;nbsp;&amp;nbsp;I hope they got it right, and I hope I get a chance to use it soon on a project.</content><link rel="alternate" type="text/html" href="http://jebsoft.blogspot.com/2006/01/clearcase-nightmares.html" title="ClearCase Nightmares" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=16787577&amp;postID=113733953920461250" title="0 Comments" /><link rel="replies" type="application/atom+xml" href="http://jebsoft.blogspot.com/feeds/113733953920461250/comments/default" title="Post Comments" /><link rel="self" type="application/atom+xml" href="http://jebsoft.blogspot.com/feeds/posts/default/113733953920461250" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/16787577/posts/default/113733953920461250" /><author><name>Joe</name><uri>http://www.blogger.com/profile/09934847924862941566</uri><email>noreply@blogger.com</email></author></entry></feed>
