drohm, Wed 03/26/08 02:24 PM
Have you ever had someone ask you what Agile is and how it can help a development team or project?  Even worse, what if that person were your boss or stakeholder?  Mike Cottmeyer does a great job of explaining it in under 30 seconds.  Nicely said.

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

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.

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5
drohm, Wed 03/21/07 02:48 PM

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.

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

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.

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

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!

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5
drohm, Tue 08/29/06 02:18 AM

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.

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

I use MSBuild and CruiseControl.NET for my automated build process.  Just yesterday I was debugging a problem in one of my assemblies and came across this warning message:

Use command line option '/keyfile' or appropriate project settings instead of 'AssemblyKeyFile'

I had never noticed the warning before, but looked into some of the past builds and noticed that it had always been there.  After doing some research, I found out that Visual Studio 2005 now considers the use of setting the AssemblyKeyFile in the AssemblyInfo.cs file a security issue.  This is due to the AssemblyKeyFile attribute being embedded within your assembly and possibly containing sensitive path information.  The warning also recommended setting this information via the project settings.  I use an external strong name key file for all of my assemblies.  It resides outside all of my projects/solutions.  When I referenced this strong name key file, VS2005 copied it into the project.  This wasn't a good thing at all.

After looking into what was going on, I noticed that in the project msbuild file, there is a property called AssemblyOriginatorKeyFile.  VS2005 automatically set it to reference the copied strong name key that it placed in the project.  I updated this path to reference my external strong name key, saved it, and deleted the local copy of the strong name key in the project.  I tested the build and it worked!

I have no idea why Microsoft designed it this way, but thankfully this method works great.

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

The new version of MSBuild Community Tasks Project was finally released back on 3/31, sorry for the late notice on that.  This new version, 1.1.0.145, has a ton of new tasks.  Some of the notables are:

  • AppPoolController
  • AppPoolCreate
  • AppPoolDelete
  • WebDirectoryCreate
  • WebDirectoryDelete
  • Xslt
  • A bunch of VSS tasks
  • A bunch of SVN tasks
  • FxCop
  • Script
  • ServiceController
  • ServiceQuery

These are just a few of the many tasks you'll find in the new library.  Be sure to check it out and download the latest version here.  We also added the ability for users to download the latest nightly builds if you so desire.  The MSBuild Community Tasks Project is an open source project.  If you don't find the task you need, join the project and help contribute.  We'd love to have you!

If you're not familiar with MSBuild, be sure to check out my articles on using MSBuild for deployment scenarios:

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

SqlAssist is a great Visual Studio add-in that gives you intellisense for SQL scripts.  There are versions for both Visual Studio 2003 and Visual Studio 2005.  It's currently still in beta, but very stable - I have yet to see any problems with it.  Some of the features are:

  • Context aware intellisense.
  • Ability to run your SQL scripts right in the IDE.
  • Uses it's own text editor that provides several convenience features: Auto-Correct Case as You Type, Comment In/Out, Insert Closing Delimiter, Standard Visual Studio Features.
  • Ability to define templates for quick and easy access to code that is used repeatedly.
  • SQL pretty formatting.
  • An object explorer modeled after the new SQL Server Management Studio explorer.

This is a great tool and most likely one you'll come to depend on.  Be sure to check it out.

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

The Patterns & Practices group has finally released the long-awaited Enterprise Library for .NET Framework 2.0:

The long-awaited update to Enterprise Library for .NET Framework 2.0 is now available - the official release is branded January 2006. This release of Enterprise Library includes six application blocks (Caching, Cryptography, Data Access, Exception Handling, Logging and Security), and provides similar functionality to the previous releases for the .NET Framework 1.1; however, Enterprise Library has been redesigned to use the new capabilities of the .NET Framework 2.0.

Make sure to download your copy today here.

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5