Bookmark and Share

Hotfixes the Easy Way

by DRohm 28. July 2007 08:06

This last week, Microsoft made available a web form that anyone can use to request hotfixes.  No more special requests or phone calls, now there's a single place where, simply by filling a web form, you can request the hotfix you want.  You can get to the form here

You will get a form mail in response, and in it will be a link to an http site you can download the fix from.

Tags:

Bookmark and Share

Who Owns the Build?

by DRohm 28. June 2007 08:27

I'd love to get some feedback on this from people. Agile or not, how do most shops handle firing off builds on their build server?  Do you let just anyone on the Development team do it?  Anyone outside the Development team do it?  A QA person?  Where does it end?

Where I work, I was given the responsibility of upgrading/re-doing our build process.  Before I finished updating it and rewriting the NAnt scripts, it was a complete and utter disaster.  Now that I've upgraded the server and build scripts to work correctly I now find myself wanting to protect it.  Before I upgraded our build setup anyone could launch a build, modify build scripts, etc.  This is true even after I did the upgrade.  The problem is I feel like there are too many cooks in the kitchen.  I cringe every time I see someone say "I'll fire off a build real fast", etc.  How do most shops handle doing builds?   By the way, I realize in a truly agile shop, this problem wouldn't exist because of the nature of Continuous Integration (it happens all the time...hence it's continuous).  Our shop isn't there yet.  I think my boss doesn't believe in any of the benefits of it.  I'm slowly trying to convince him, but have a lot of work to do in that area.

So, do most shops have a dedicated build master that handles the builds?  Or do they let just anyone tinker with the build, modify scripts, or launch builds?

Bookmark and Share

CoComment for CS2007 Made Easy

by DRohm 11. June 2007 16:53

If you don't know what CoComment is, be sure to follow the link and find out. It's an easy way for you to keep track of your conversations that you have on the net (replies to forums, blogs, etc...). Back when I was running CS 2.x, I had CoComment setup with my installation so that users who were posting replies to my site could easily authenticate with CoComment so that it could track their conversations. I never got around to figuring that out for CS 2007, but luckily I didn't have to - Thomas Freudenberg did all the work! He created a dll that you drop into your bin folder and add one line to ~/App_Browsers/default.browser:

<adapter controlType="CommunityServer.Blogs.Controls.WeblogPostCommentForm"

        adapterType="ThomasFreudenberg.CS2007.WeblogPostCommentFormAdapter, ThomasFreudenberg.CS2007" />

The beauty of adding his code to a control adapter is that he just specifies which controls need to be customized.  There isn't a need to modify any blog pages or controls.  Very clean.

Tags:

Bookmark and Share

TestDriven.NET vs. Microsoft?

by DRohm 30. May 2007 17:47

Jamie Cansdale just blogged about his entire ordeal that he's going through with Microsoft over how he integrated TestDriven.NET with the Express edition of Visual Studio.  I encourage you to read through the entire correspondence, its eye-opening to say the least.

I'm a paying user of TestDriven.NET, absolutely love the product, and don't want it to go away.  That said, I do think Jamie should just remove support for the Express versions of Visual Studio.  I don't think anyone in the community would have negative feelings towards him or his product by doing this.  If anyone reads his blog, they would know that his integration with the Express SKU wasn't a "hack" (it used publically listed API's).

Having already lost NDoc, due to completely different reasons, the thought of losing TestDriven.NET would hurt...bad.

Tags:

Bookmark and Share

Book Review: Use Case Driven Object Modeling with UML - Theory and Practice

by DRohm 24. May 2007 17:19

I just finished reading this book and thought I'd give a quick overview of it and my feelings on the book.

Quite simply, I loved the book. This was my first exposure to the ICONIX Process (created by Doug Rosenberg) and I would love to try to put this process in action on a future project. It's logical, systematical, and easy to learn. The real challenge is in sequence diagramming. The authors are very good at explaining the topic in a very easy-to-read and engaging style. The entire ICONIX process is discussed from beginning to end while implementing a Java/Spring bookstore web site.

ICONIX is considered an agile methodology. Taken right from the book: "ICONIX Process is a minimalist, streamlined approach that focuses on that area that lies in between use cases and code. Its emphasis is on what needs to happen at that point in the life cycle where you're starting out: you have a start on some use cases, and now you need to do good analysis and design." ICONIX originated several years before the UML and combined the best techniques from the "Three Amigos" (Ivar Jacabson, Jim Rumbaugh, and Grady Booch). The three methods, Ivar Jacobson's Objectory method, Jim Rumbaugh's Object Modeling Technique, and Grady Booch's 'Booch method', were combined by taking the best features of each method and integrating them into a lifecycle approach. The three UML modeling techniques used are Use Cases, Robustness Diagrams, and Sequence Diagrams. Robustness diagrams are a nice tool that helps bridge the gap for designers to get from Use Case's to Sequence Diagrams (from analysis to design).

Each chapter in the book starts out with a graphic (like the one listed above) of the area you're currently in printed in red. This helps the reader know exactly where they are in the process. Every chapter also gives a "Top 10 Guidelines" list for the topic and explains each point in detail throughout the chapter. At the end of each chapter there are exercises and practice problems to help to reinforce the topic just covered.  Also at the end of each chapter is a flow chart that shows the current step in the process in detail.  This summarizes the chapter by showing each sub-step in the process, which I found quite informative. The example used throughout the book is an internet bookstore and the authors explain 2-3 use cases from chapter to chapter. This allows you to see first-hand how a requirement becomes a use case and a domain model, then a robustness diagram with an updated domain model, which then leads to a detailed sequence diagram and a full-blown class diagram, which then easily transitions to real code. Thats what I really like most about the ICONIX process. The concepts are not new, they just follow a logical flow from requirements to code in the fastest way possible, losing most, if not all, ambiguity and vagueness of the system. What a novel concept!

The book is very well written with few mistakes (code or grammar). The authors go through each topic with an in-depth explanation and offer advice at every turn. Another nice tidbit I really enjoyed is in the chapter on Sequence diagramming, the authors list several quality OOAD books for further reading. For example, Object Design: Roles, Responsibilities, and Collaboration, which I'm now currently reading. Another book they mention for further reading is Object-Oriented Analysis and Design with Applications (the 3rd edition for this book just came out).

The book uses Enterprise Architect from Sparx Systems as the main modeling tool during the book. They also use MDG Integration for Visual Studio 2005 in Chapter 10 - Implementation: Getting From Detailed Design to Code and also in Chapter 11 - Code Review and Model Update to keep the code and design diagrams in sync.

If you're interested at all with software methodologies and processes, I highly recommend this book.

Tags:

Bookmark and Share

CopySourceAsHtml 2.0.0

by DRohm 23. March 2007 17:40

I realize this is a tad-bit old, but I haven't checked for an update to this add-in in quite some time.  I wrote about how to get the previous version of CSAH running under VS2005, but realized there is a new version fully compatible with VS2005 and .NET 2.0.  Straight from the CSAH web site:

CSAH 2.0.0 is the first official release of CopySourceAsHtml for Microsoft Visual Studio 2005. This release has a leaner, meaner, refactored codebase that fixes a few minor defects and takes advantage of new features in Visual Studio 2005 and .NET 2.0.

CSAH is the one and only source copying tool I use for blogging.  Simply awesome.

Go check it out here.

Tags:

Bookmark and Share

VisualSVN 1.1 Released

by DRohm 21. March 2007 14:48

A new version of VisualSVN was released yesterday packing a whole load of new features, the most significant being status icons for files and folders in Solution Explorer.  This new version is built against Subversion 1.4.0 and TortoiseSVN 1.4.1.7992.  Be sure to download both before installing this version.  Here is a list of the new features:

  • Status icons for files and folders in Solution Explorer.
  • Transparent deletion of files and folders from Subversion when Visual Studio removes them from disk.
  • New commands Checkout, Branch, Switch.
  • Evaluation license is valid for all users.
  • Several bug fixes and usability improvements.

Here is a screenshot of my Solution Explorer showing the new status icons:

In the options, you have a choice between 'traffic lights' status icons or 'high contrast' status icons.  I prefer the 'traffic lights' status icons (the ones in the screenshot above).  Enjoy.

Tags:

Bookmark and Share

ESPN Unbiased?

by DRohm 6. October 2006 18:03

As I'm writing this post Detroit is beating New York 6-0 in game 2 of the ALDS. Earlier, I watched Oakland beat Minnesota to win its division series 8-3.  Oakland now advances to face either Detroit or New York in the ALCS.  Detroit and New York's series is currently tied one game each in a best of 5 series. I was reading the write-up for the Oakland game on ESPN and found a disturbing sentence in the article (which you can read here):

On Deck
The A's advance to the American League Championship Series for the first time since 1992. Game 1 of the ALCS will be played on Tuesday in either New York or Oakland.

The last part of that is what really pisses me off.  Is ESPN assuming New York will beat Detroit?  I thought ESPN was all about reporting sporting news and not what they "think" or "hope" will happen.  I love ESPN, but it seems to be they're going too far.  The only explanation I can think of would be if its based off of home-field advantage.  If it is, I think it should have been worded differently.

Thoughts?

Tags:

Bookmark and Share

Visual Studio and Subversion Together at Last!

by DRohm 2. September 2006 00:07

Finally, a good Visual Studio add-in for subversion, VisualSVN.  I just found out about this plugin yesterday and so far have been using it without any problems or issues. It integrates with Visual Studio and uses TortoiseSVN to perform its actions. It also creates a new menu to access all of the Tortoise functions.  When you invoke any of the actions it creates a new Tortoise screen as a modal window over Visual Studio.  Here is a quick screenshot:

You can use the fully functional demo version free for 30 days.  After that, you can register it for a measly $19.  It's well worth the money in my opionion. I highly recommend this plugin for anyone doing .NET development with subversion as your source control repository.

Tags:

Bookmark and Share

Updated Ultimate Developer and Power Users Tool List

by DRohm 29. August 2006 10:57

Scott Hanselman just released a new and improved list of tools for developers and power users:

Scott Hanselman's 2006 Ultimate Developer and Power Users Tool List for Windows

If you've seen his previous lists, this one won't disappoint.  I'm always guaranteed to fine a gem or two here.  I have to admit that its satisfying to see another CodeRush fan.  If you're a geek, power user or developer, go check it out.  There are tools in his updated list you didn't know you needed until you saw them.  Definitely worth the read!

Tags:

Bookmark and Share

Predicates and Elegant Code

by DRohm 29. August 2006 02:18

About a month ago I used one of the new features built into .NET 2.0 and didn't realize its power until just yesterday after reading an MSDN article by Ken Getz and then a blog post by Chad Finsterwald. When I first used Predicates I knew it was something that helped my code look 'cleaner' but not to the degree I found yesterday. In case you're not familiar with Predicates, they are new to .NET 2.0 and are used by collections such as Array and List to perform methods such as RemoveAll, Find, FindAll, Exists, etc.  As the MSDN documentation points out, a predicate is a delegate.  As long as the method signatures are the same then any method that conforms to the signature of the Predicate can be called in its place.  The biggest benefits of using Predicates is that they allow your code to be more expressive and promote code reuse.

I'll explain how I was using predicates initially and then show how I improved the design.  In my web application, I'm using a LookupManager class that looks up items in a database.  One of the uses for this class is to get items for say, a state dropdown control.  Each item in the state list has an Id that is reflected in the database.  In my case, I'm using Guid's as the primary key.  I don't want to insert Guid's as the value for each ListItem in the aspx page, so I'm masking those Id's.  In order for me to search the list from a postback so that I can map the MaskedId back to the original Id, I need to make use of the List's Find method.  This is where predicates help make my code cleaner.

Here is my initial implementation:

        public LookupItem GetItem(LookupType type, IdentityField id)

        {

            _searchLookupItemId = id;

            List<LookupItem> items = Lookup(type);

            LookupItem foundItem = new LookupItem();

            foundItem = items.Find(LookupItemMatchById);

 

            return foundItem;

        }

 

        public LookupItem GetItem(LookupType type, int maskedId)

        {

            _searchLookupItemMaskedId = maskedId;

            List<LookupItem> items = Lookup(type);

            LookupItem foundItem = new LookupItem();

            foundItem = items.Find(LookupItemMatchByMaskedId);

 

            return foundItem;

        }

These two methods allow me to search the List by either the Id or MaskedId.  Each one calls the List's Find method, passing in the predicate method.  Here are those methods:

        #region LookupItemMatchById(LookupItem searchItem)

        /// <summary>

        /// Predicate that finds the <see cref="DougRohm.Solid.Domain.LookupItem"/> by matching Id's.

        /// </summary>

        /// <param name="searchItem">Item to search.</param>

        /// <returns>Boolean indicating if a match was found.</returns>

        private bool LookupItemMatchById(LookupItem searchItem)

        {

            if (searchItem.Id.Value.Equals(_Id))

            {

                return true;

            }

 

            return false;

        }

        #endregion

 

        #region LookupItemMatchByMaskedId(LookupItem searchItem)

        /// <summary>

        /// Predicate that finds the <see cref="DougRohm.Solid.Domain.LookupItem"/> by matching MaskedId's.

        /// </summary>

        /// <param name="searchItem">Item to search.</param>

        /// <returns>Boolean value indicating if a match was found.</returns>

        private bool LookupItemMatchByMaskedId(LookupItem searchItem)

        {

            if (searchItem.MaskedId.Equals(_MaskedId))

            {

                return true;

            }

 

            return false;

        }

        #endregion

One thing to note here.  In each GetItem method above, I'm setting member variables that tell each predicate what to search for.  This is one of the limitations to predicates - you can't pass parameters to them.  Using member variable is a way to get around this.  The main problem with that is that it clutters up the LookupManager class.  Not only is the class cluttered with the predicates themselves, but now I'm adding more member variables. Afterall, what does the LookupManager class have to do with Finding items based on Id's or MaskedId's?  Too much noise.

The ultimate solution to this is to wrap those member variables and the predicates themselves into its own class.  This allows for even greater code reuse and simplifies the LookupManager class at the same time.  Here is my final solution:

    /// <summary>

    /// Custom predicate class used to search a <see cref="DougRohm.Solid.Domain.LookupItem"/> collection

    /// by either it's Id or MaskedId.

    /// </summary>

    public class LookupItemIdMatch

    {

        #region Fields

 

        private IdentityField _Id;

        private int _MaskedId;

 

        #endregion

 

        #region Properties

 

        public IdentityField Id

        {

            get { return _Id; }

            set { _Id = value; }

        }

 

        public int MaskedId

        {

            get { return _MaskedId; }

            set { _MaskedId = value; }

        }

 

        public Predicate<LookupItem> MatchId

        {

            get { return LookupItemMatchById; }

        }

 

        public Predicate<LookupItem> MatchMaskedId

        {

            get { return LookupItemMatchByMaskedId; }

        }

 

        #endregion

 

        #region Constructors

 

        public LookupItemIdMatch(IdentityField id)

        {

            _Id = id;

        }

 

        public LookupItemIdMatch(int maskedId)

        {

            _MaskedId = maskedId;

        }

 

        #endregion

 

        #region Predicates

 

        #region LookupItemMatchById(LookupItem searchItem)

        /// <summary>

        /// Predicate that finds the <see cref="DougRohm.Solid.Domain.LookupItem"/> by matching Id's.

        /// </summary>

        /// <param name="searchItem">Item to search.</param>

        /// <returns>Boolean indicating if a match was found.</returns>

        private bool LookupItemMatchById(LookupItem searchItem)

        {

            if (searchItem.Id.Value.Equals(_Id))

            {

                return true;

            }

 

            return false;

        }

        #endregion

 

        #region LookupItemMatchByMaskedId(LookupItem searchItem)

        /// <summary>

        /// Predicate that finds the <see cref="DougRohm.Solid.Domain.LookupItem"/> by matching MaskedId's.

        /// </summary>

        /// <param name="searchItem">Item to search.</param>

        /// <returns>Boolean value indicating if a match was found.</returns>

        private bool LookupItemMatchByMaskedId(LookupItem searchItem)

        {

            if (searchItem.MaskedId.Equals(_MaskedId))

            {

                return true;

            }

 

            return false;

        }

        #endregion

 

        #endregion

    }

There are two constructors to the class, one that takes an IdentityField and one that takes an int.  I can instantiate this class with the appropriate Id that I plan to use.  Also, there are two properties that return predicates, MatchId and MatchMaskedId.  Each property returns the appropriate internal predicate for use in external code. To use this new class back in my LookupManager class in the GetItem methods I simply 'new' up an instance of this class:

        #region GetItem(LookupType type, IdentityField id)

        /// <summary>

        /// Gets a <see cref="DougRohm.Solid.Domain.LookupItem"/> based on the Id.

        /// </summary>

        /// <param name="type">A <see cref="DougRohm.Solid.BLL.LookupType" /> for the search.</param>

        /// <param name="id">The <see cref="DougRohm.Solid.Domain.LookupItem.Id"/> for the search.</param>

        /// <returns>Returns a <see cref="DougRohm.Solid.Domain.LookupItem"/>.</returns>

        public LookupItem GetItem(LookupType type, IdentityField id)

        {

            List<LookupItem> items = Lookup(type);

            LookupItem foundItem = new LookupItem();

            foundItem = items.Find(new LookupItemIdMatch(id).MatchId);

 

            return foundItem;

        }

        #endregion

 

        #region GetItem(LookupType type, int maskedId)

        /// <summary>

        /// Gets a <see cref="DougRohm.Solid.Domain.LookupItem"/> based on the Masked Id.

        /// </summary>

        /// <param name="type">A <see cref="DougRohm.Solid.BLL.LookupType" /> for the search.</param>

        /// <param name="maskedId">The <see cref="DougRohm.Solid.Domain.LookupItem.MaskedId"/> for the search.</param>

        /// <returns>Returns a <see cref="DougRohm.Solid.Domain.LookupItem"/>.</returns>

        public LookupItem GetItem(LookupType type, int maskedId)

        {

            List<LookupItem> items = Lookup(type);

            LookupItem foundItem = new LookupItem();

            foundItem = items.Find(new LookupItemIdMatch(maskedId).MatchMaskedId);

 

            return foundItem;

        }

        #endregion

As you can see in each method, I call the Find method on the List items and instantiate the LookupItemIdMatch class passing in the search item.  I then call the property to return the correct predicate. I like this solution, its clean, elegant, and promotes code reuse. Oh, there is one other benefit to using predicates, they run faster than if you were to use foreach loops.  The performance increase isn't earth shattering, but faster nonetheless.

I hope in showing how I made use of predicates can help you.

Tags:

Bookmark and Share

Dynamically Setting Parameters for DataSourceControls

by DRohm 9. August 2006 13:28

Using the ObjectDataSource and either a GridView or DetailsView you can very easily create data-driven web sites.  What's even better about using these controls is that they give the developer a way to create data-driven pages without writing a single line of code.  All of this is great and extremely useful, up until you need to do more customized solutions.  For instance, what do you do if you need to dynamically set parameter values in the code-beside file for a GridView or DetailsView control?

You can do this by handling the appropriate event for the DataSourceControl.  The events listed below all fire before their business class methods are called making them the perfect place to do your changes or updates.

  • Selecting
  • Inserting
  • Updating
  • Deleting

There are other events you can catch and handle, but for the purposes of what we want to do, these are the events of interest.  Each of these events contain an InputParameters collection, passed in by the ObjectDataSourceMethodEventArgs parameter. Once inside the event, you can set the value of the parameter you need to modify and thats it.  Here is an example of catching the Inserting event and setting the value of the "audit" parameter.  In this case, the DetailsView is bound to a business class object.  The InsertMethod for the DetailsView has an 'audit' parameter that we need to set dynamically when the event is fired:

        protected void objCurrOption_Inserting(object sender, ObjectDataSourceMethodEventArgs e)

        {

            e.InputParameters["pollId"] = new IdentityField(e.InputParameters["pollId"].ToString());

            e.InputParameters["audit"] = new Audit(CurrentUserName, CurrentUserIP, CurrentUser);

        }

Again, this event is fired before the method on the business object is called. You can use the same method to dynamically set values for Updates, Deletes, and Selects.

Tags:

Bookmark and Share

Atlas July CTP Released

by DRohm 1. August 2006 05:32

The July CTP of Atlas was released yesterday mostly as a bug-fix release. The details of the release are:

UpdatePanel and ScriptManager:
  • ScriptManager.RegisterControl() takes optional parameter to specify client type to create.
  • Fix for UpdatePanels in Firefox.
Drag and Drop:
  • Added public dragStart/dragEnd events to DragDropManager.
  • dragStart fires with dragMode, dataType, and data as eventArgs.
  • dragStop fires with empty eventArgs.
  • style.position of dragVisuals will no longer default to "absolute".
  • DragDropManager do longers disposes dropTargets when unregistering them.
  • FloatingBehavior now unregisters itself on dispose.

Head over to the Atlas web site to download the new version.

Tags:

Bookmark and Share

Community Server 2.1 Beta 2

by DRohm 30. July 2006 17:16

Well, from the looks of things, hopefully you'd notice that I got CS 2.1 Beta 2 running this weekend.  Overall, an okay upgrade experience.  I only had one flaw, which took me 2-3 hours to troubleshoot.  Other than that, it was smooth sailing, kind of a shame I ran into that problem though.  I ran the SQL upgrade script without a problem, all green.  I then copied up the entire CS 2.1 web contents.  Updated the web.config and then went to login and got an ASP.NET profile error.  It took me awhile to figure it out, but all I needed to do was run another SQL script that came with CS 2.1 Beta 2 (the installation instructions didn't mention to run that file).  It needed to update the Membership schema, once that was done it worked perfectly.  So far I haven't encountered a single problem or error with this newest beta, but if you do run into a problem, be sure to email me and I'll report the issue to the CS team.

Thanks to Kris Cargile's recent CS upgrade, I also started using Ken Robertson's Qgyen.ExtendedUrlMapping for CS 2.1.  This add-on allows you to very easily run a single blog for a CS installation and it works perfectly.

I've also installed the Aero theme for CS 2.1 and its awesome.  It's a site-wide theme and not just for blogs, photos, or anything else.  It's for every page, including the admin pages.  It didn't take that long to setup and its pretty easy to configure.  The only thing that took a lot of time setting it up was uploading all of the background images :)  While I was doing that I very quickly came to the realization that the actual handling of photos in the photo area of CS is very lacking.  All of the operations for photos are based on a single photo.  There isn't an easy way to delete multiple files.  There isn't an easy way to move multiple files, and most importantly, there isn't an easy way to upload multiple files.  Very frustrating...until I found the CS Gallery Manager 1.2 by Duncan Menzies.  What a great tool that allows you to upload multiple images to your CS server.  It allows you to add a title, and description and you can specify which album to place the uploaded photos.  It's a standalone windows application so there is nothing to configure with CS.

Again, if you run into any problems with the site, please contact me so I can get any issues with the beta reported to the CS team.  Thanks.

Tags:

Bookmark and Share

Microsoft to Release 'Documentation Compiler' (Sandcastle)

by DRohm 19. July 2006 18:05

I just read on the Microsoft forum's that Microsoft has announced its upcoming tool for generating MSDN-like documentation from your .NET code.  The product's codename is 'Sandcastle' and is presented as a 'Documentation Compiler'.  It will work just about the same as NDoc and of course will work with .NET 2.0.  I guess Microsoft actually listed to our requests.

The new tool is what Microsoft used internally to generate the .NET Framework documentation.  Source code will not be made available though, but they mention that updates will be done in monthly iterations.

Finally...

Tags:

About Me

Doug Rohm
Twitter Technorati

Doug Rohm
Boston area .NET developer, geek, gamer, dog lover, and sports nut.