Josh Heyse

Thoughts Defragmented

Archive for October, 2008

VSTS User Group Presentation – VSTS for Database Developers

Posted by jheyse on 18th October 2008

I’ll be presenting at the Visual Studio Team System User Group next month on the features Visual Studio Database Edition provides and how it makes developers more productive.  Recently Microsoft announced it would combine VSTS Database and VSTS Developer since most developers also interact with the Database.  I think this is an extremely smart move on their part because it allows developers to build databases better.  I will be presenting at the Chicago Loop meeting and Paul Hacker will be presenting in Downers Grove.

Official Announcement

On September 29, 2008, Microsoft announced that Visual Studio Team System Development Edition will be combined with the Visual Studio Team System Database Edition in Visual Studio Team System 2010.  Microsoft recognized that many developers write front end code in addition to working deeply with database code and database tables. Bringing the feature of Team Development Edition and Team Database Edition together sets together enables you to take advantage of the core tools for application development as well as the necessary tools for database development, including performance profiling, code analysis, code metrics, code coverage, database refactoring, Schema Compare, Data Compare, and more.  You may also be happy to know there is a way to take advantage of this 2 for 1 deal TODAY.  Really, no joke!

Want to hear more about it?  Maybe even see these two incredibly powerful tools together?  Join the Chicago Visual Studio Team System User Group to hear more about how to get your hands on this awesome duo of tools, talk to field experts about how these tools have improved their overall quality of life (OK, maybe just their work environment), and to see them in action!.  We have decided to hold this session in both the Chicago Loop and Downers Grove offices to ensure everyone has a chance to learn about this terrific new opportunity.

To sign up, please email Laskowski.Dave@gmail.com. Please indicate which meeting you plan to attend.

Meeting Agenda
5:30pm – Pizza
6:00pm – Introductions
6:15pm – Presentation and Demo
7:30pm – Q&A and Raffle

Chicago Loop Meeting Details:
Wednesday November 5th, 2008
77 West Wacker Drive, 23rd Floor, Chicago, IL
Map

Downers Grove Meeting Details:
Wednesday October 29th, 2008
3025 Highland Parkway, 3rd Floor, Downers Grove IL
Map

Speaker Bios:

(Downers Grove)
Paul Hacker is a Principle Consultant at Polaris Solutions, LLC in Indianapolis, with a passion for Team System. He has been working with the product since beta 3. Paul has implemented Team System/TFS in numerous organizations. When not spending time with his family, you can find him presiding over the Indianapolis TFS SIG, Podcasting on Radio TFS or writing tools to enhance Team System. You can reach Paul at paul.hacker@polarissolutions.com

(Chicago Loop)
Josh Heyse is a Senior Solution Architect with Catalyst Software Solutions. He has always focused on staying ahead of the technology curve, investigating Microsoft technologies before they are available to the general public. Josh began developing on beta versions the .NET Framework when they were released in early 2001. Josh is currently focused on WPF, LINQ, and most recently Silverlight 2.0.  As an architect Josh spends a lot of time improving the software development lifecycle by implementing pattern & practices, continuous integration and ALM tools such as Team Foundation Server. MCSD, MCDBA, MCPD

Posted in Application Lifecycle Management, Speaking, TFS, Visual Studio | No Comments »

Dynamic Data Filtering – Table Text Search

Posted by jheyse on 17th October 2008

I’m pretty happy with the number of people who have been downloading and trying out Dynamic Data Filtering.  On average there are about 20 downloads a day with around 50 page views.  There has been a lot of good feedback on both the ASP.NET forums and on the CodePlex project site 5over the last week or so.  So much actually that I am having trouble keeping up with answering the questions coming in. 

One question did catch my eye though.  It was a member of the ASP.NET forum asking about being able to search on all of the columns within a given table.  [View the Post]  Dynamic Data doesn’t support this functionality out of the box, but it is flexible enough to write something yourself to do it.  The main things that makes this possible is that a single FilterTemplate can return one ore more DynamicFilterParameters which produce lambda predicates.

In this case, you can accomplish this logic of searching multiple columns in a table by saying where ProductName LIKE [Value] or ProductNumber LIKE [Value] etc…  To accomplish this in Dynamic Data Filtering you would utilize the OrExpressionParameter to create a collection of LikeExpressionParameters to do the predicate for each individual column.

I spent a little time creating a simple example which performs this logic.  I also implemented a Columns property which allows you to specify using a comma separated list the columns you want searched.  If Columns is left null or empty all columns are searched.  The aspx for the user control only contains a single asp:TextBox with the Id=TextBox1.

public partial class TableTextSearch : Catalyst.Web.DynamicData.FilterTemplateUserControlBase
{
    public string Columns { get; set; }
 
    private MetaTable Table
    {
        get
        {
            IDynamicDataSource source = this.FindDataSourceControl();
            if (source != null)
                return source.GetTable();
            return null;
        }
    }
 
    public override IEnumerable<Parameter> GetWhereParameters(System.Web.DynamicData.IDynamicDataSource dataSource)
    {
        OrExpressionParameter parameter = new OrExpressionParameter();
 
        string[] cols = null;
        if (!string.IsNullOrEmpty(Columns))
        {
            cols = Columns.Split(',');
            for (int i = 0; i < cols.Length; i++)
                cols[i] = cols[i].Trim().ToUpper();
        }
 
        var columns = (from c in Table.Columns
                       where cols == null || cols.Length == 0 || cols.Contains(c.Name)
                       group c by c.TypeCode).ToDictionary(g => g.Key, g => g);
 
        foreach (var column in columns[TypeCode.String])
        {
            parameter.Parameters.Add(new LikeExpressionParameter()
                    {
                        Type = TypeCode.String,
                        Name = column.Name,
                        Value = TextBox1.Text,
                        Like = LikeExpressionParameter.LikeType.Contains
                    });
        }
        yield return parameter;
    }
 
    public override void LoadQueryStringParameters(System.Collections.Specialized.NameValueCollection parameters)
    {
        TextBox1.Text = parameters["TableTextSearch"];
    }
 
    public override System.Collections.Specialized.NameValueCollection SaveQueryStringParameters()
    {
        return new NameValueCollection() { { "TableTextSearch", TextBox1.Text } };
    }
 
    public override void Clear()
    {
        TextBox1.Text = string.Empty;
    }
}

To implement filters like this one you must use the DynamicFilterForm as opposed to the DynamicFilterRepeater.  The reason is that the TableTextSearch filter control is associated with any column/property in particular but the entire table instead.  It may make sense to allow the FilterAttribute to be annotated at the class level to address this.

<asp:DynamicFilterForm ID="DynamicFilterForm1" runat="server" DataSourceID="GridDataSource">
    <FilterTemplate>
        <div>
            Search
        </div>
        <div>
            Keyword: 
            <dd:TableTextSearch runat="server" ID="TableTextSearch" />
            <asp:LinkButton ID="LinkButton4" runat="server" CommandName="Search">Search</asp:LinkButton>&nbsp;&nbsp;
            <asp:LinkButton ID="LinkButton5" runat="server" CommandName="Clear">Clear</asp:LinkButton>
        </div>
    </FilterTemplate>
</asp:DynamicFilterForm>

To build upon this example it would be nice to be able to search the DisplayText of foreign columns and potentially non text values.  For example if the user entered a string which can be converted to a date, search all DateTime columns.

Posted in ASP.NET, Dynamic Data, LINQ | No Comments »

Silverlight 2 At Last

Posted by jheyse on 14th October 2008

After what seems like forever, Microsoft has released the final bits for Silverlight 2.  The product has come an extremely long way since it’s code name of WPF/E and its formal introduction as Silverlight 1.1 during Mix 07.  I am ecstatic about the concept of Silverlight and the RIA potential it brings developers.  While my professional development roots started with the web, I’ve always felt that HTML & Javascript based applications have always been a kludge.  The stateless, scripted environment built on what started as a linkable document format quickly outgrew it’s original architecture.

Silverlight 2 brings us that green field development experience all developers dream of.  The "I could do this so much better only if I didn’t have to worry about …" feeling we all get when digging into an existing code base.  Now that Microsoft has released the technology it is up to us, the developer community, to start creating best practices around developing on this new technology.  It is looking to be an excellent next year for Rich Internet Application space.

Tim Heuer has an excellent blog post on what you need to get started with Silverlight 2 development.  On a very interesting side note, Eclipse will have support for Silverlight 2… cross browser, cross platform and cross IDE.

Posted in Silverlight, Visual Studio | No Comments »

ALM – Source Control

Posted by jheyse on 6th October 2008

Source control, or revision control, is part of almost every developers daily activities.  Some days, it is their only activity.  Especially those still using Visual Source Safe. :) Yet it seems that many of us have an extremely hard time with this vital software development tool. I believe this is because of two reasons: 1) it is hard! 2) we are never really taught source control in school. 

My first experience with source control was when I started my internship during freshman winter break.   Never once in the next 6 years of schooling was source control taught.  We had a few classes which used source control, but it was assumed that everyone knew how to use it.  In my experience, developers typically are shown how to use source control during their first day or two on the job by another developer, after that it’s "don’t break the build". 

So why is source control so hard?  Well you have a lot going on.  Ask any developer who has ever worked on a project with an occasionally connected system and they will tell you that the master to master synchronization between the two data sources was the most complicated aspect of the system.  What was meant to change? How do I handle conflict?  Was this deleted from one system or created in another?  To manage this the developer usually tries to accomplish a small set of synchronization rules, but leaves the rest to the user to decide what the intention of the synchronization was.  This means that the users need to be taught how to use the tool.  In our case, as developers, there are very few rules and the onus is on us to correct anything the system can’t figure out.

In addition to source control being hard, we have made it harder by implementing it two different ways, exclusive check-out/in and version merging repositories.

Visual Source Safe is an exclusive source control system which means that the system only allows one person to check-out a file; all other users can read the file but not write to it.  Once the user is done they check-in their change set. This is the ’safest’ form of source control to prevent against unwanted sides effects within a single file.  Most developers on the Microsoft platform are used to this version.

Team Foundation Server (by default) and Subversion are version merging repositories.  This means that everyone has the ability to write to their local files.  When the developer is done with their changes they merge them with the current version within the repository.  Because you do not exclusively check out files you aren’t ensured that the file hasn’t changed since you started working with it.  The developer, that’s you, must carefully merge the two files together.  The source control merge tool checks for conflicts at the line level.  This means that if a given line is changed in either the local or server copy the source control will accept the change automatically.  If both lines have changed, a merge conflict is logged and the user will be prompted to correct the issue.  I will be going into more detail on how to handle merge conflicts in a later post.

One of my roles within Catalyst as an architect and our TFS admin has been to define a source control process for projects moving forward.  I will also be working to educate our developers on that process and to depend their knowledge of source control usage.  This is going to be done through my blog and several presentations given during Lunch & Learns.  These presentations are also available to our clients, if they would like to attend.

When I first create a project in Team Foundation Server, I immediately create the following folders under the root of that source control repository:

  • trunk
  • branches
  • releases

The trunk is where you build and deploy from, no development is done in the trunk.  Developers when assigned a task create a branch under branches, sometimes called dev, for their development.  This is where they begin to code.  This allows them to check code into the server before they have completed their tasks and it will not impact other developers or the build.  This also gives architects or team leads to ability to review code before it is merged into the trunk.

After a developer is done with a task, they merge their branch back into the trunk.  During this time they check to ensure that the code they are checking in doesn’t reference any code that has changed, due to other developers merging into the trunk. Building and running automated unit tests are the easiest ways to due a quick gut check.  In larger projects, someone or even a team is responsible merging into the trunk. 

When the deployment team goes to make a release build they branch the trunk to releases.  QA and support begin working with the release branches so not to impact new development.  Subsequent patches when released are then branched using a majorminorrevision hierarchy.  If a bug is identified to affect the trunk, the code which resolved the bug is also merged with the trunk. 

From a testing point of view, unit testing is performed at the branch level before merges can be performed. Complete unit testing and functional testing is done on the trunk nightly.  The trunk is also where most of the reporting is performed such as static code analysis, code churn, etc…

Posted in Application Lifecycle Management, TFS | No Comments »

Team Foundation Server & Application Lifecycle Management

Posted by jheyse on 3rd October 2008

Last month Catalyst Software Solutions, my employer, official became a member of the Visual Studio Team System Inner Circle.  We have been working with Angela Binkowski over the last couple of months to complete our enrollment within the Inner Circle.  This effort was driven by Dan Noone and he engaged me to help with the practice.

So, what is the Inner Circle?  Well instead of trying to put it into my own words, I am going to grab the overview from the Microsoft document:

The Visual Studio Team System Inner Circle is an initiative (“VSTS Inner Circle”) to train, enable and engage with a key set of specialized application life-cycle management partners worldwide who:

  1. Commit to meeting enrollment requirements (by the end of the Inner Circle initiative) for future Application Life-cycle management sub-specialization within the Microsoft Partner Program’s Custom Development Solutions competency
  2. Engage deeply with the Developer & Platform Evangelism (“DPE”) sales and marketing field to proactively drive solution sales of Visual Studio Team System software development tools;
  3. Deliver one or more consulting/implementation/training service offerings to enable customers to improve their development capabilities and achieve ROI on their Team System tools investment, for example:
    • Instructor led deep-dive training/coaching workshop services
    • Customization, integration/extension, and deployment services
    • Process design & Improvement consulting services
    • Software Quality implementation/Testing services
  4. Proactively share engagement best practices/learnings with Inner Circle partner community
  5. Provide constructive feedback to advance adoption and sales of Team System products

Inner Circle is a bridge initiative delivered in conjunction with the Microsoft Partner Program to assist deeply committed Team System partners prior to the launch of the Application Life Cycle Management specialization within the Microsoft Partner Program’s Custom Development Solutions Competency. Inner Circle is currently limited to ~ 300 partners worldwide and will become Microsoft Partner Program’s new Application Life Cycle management specialization.

I am super excited about this because software engineering is one of my passions and I now get to spend more dedicated time working with the process and tools which make developing software easier, faster, and more enjoyable.  I’ve had a lot of background in the area in school with my B.S. in Computer Science followed by another two years studying Software Architecture and Project Management during my M.S. in Software Engineering.  Since then I, as many developers have, worn all hats of the software development lifecycle at some point or another.

So, what does this mean?  Well first off it means you will start seeing more TFS content on my blog.  I will be starting a series of posts around Team Foundation Server, the Visual Studio Tools, and Application Lifecycle improvements.  Catalyst is also going to begin hosting VSTS Lunch & Learn sessions which will help introduce our clients and perspective clients to the benefits of VSTS.  These sessions will typically also be available as screen casts and potentially webinars.  I’ve also committed to be speaking at user groups around the area, starting with the VSTS user group in early November.

So stay tuned for content and event announcements I will post them regularly.

Posted in Application Lifecycle Management, Inner Circle, TFS, VSTS | No Comments »

ASP.NET Dynamic Data Filtering – DynamicFilterRepeater

Posted by jheyse on 1st October 2008

One of the new features I released with Dynamic Data Filtering 1.10 is the DynamicFilterRepeater control.  This control was added based on requests from several people who have implemented Dynamic Data Filtering in their applications.  The idea is to use the model metadata to generate the set of filtering controls on each page as opposed to using the DynamicFilterForm.  This is a great addition because it allows developers to annotate their model and modify their PageTemplates to get full Dynamic Filtering capabilities throughout the site.

The first step in using the DynamicFilterRepeater is to replace the existing FilterRepeater on either the DynamicDataPageTemplatesList.aspx or DynamicDataPageTemplatesListDetails.aspx page. 

In this example we will focus on the List.aspx page. On the List.aspx page, the default FilterRepeater controls looks something like:

<asp:FilterRepeater ID="FilterRepeater" runat="server">
    <ItemTemplate>
        <asp:Label runat="server" Text='<%# Eval("DisplayName") %>' AssociatedControlID="DynamicFilter$DropDownList1" />
        <asp:DynamicFilter runat="server" ID="DynamicFilter" OnSelectedIndexChanged="OnFilterSelectedIndexChanged" />
    </ItemTemplate>
    <FooterTemplate><br /><br /></FooterTemplate>
</asp:FilterRepeater>

Delete it!

Next drag the DynamicFilterRepeater from the tool box on to the form. You will get markup that looks like the following:

Tip: I HIGHLY recommend you do this in the designer view.  If you do you will get prompted to create the FilterTemplates directory, if it is not already created.  References to Catalyst.Web.DynamicData and Catalyst.ComponentModel.DataAnnotations will also be added.

<asp:DynamicFilterRepeater ID="DynamicFilterRepeater1" runat="server">
    <HeaderTemplate>
        <div>
            Search</div>
    </HeaderTemplate>
    <ItemTemplate>
        <div>
            <asp:Label ID="Label1" runat="server" Text='<%# Eval("DisplayName") %>'></asp:Label><asp:DynamicFilterControl
                ID="DynamicFilter" runat="server">
            </asp:DynamicFilterControl>
        </div>
    </ItemTemplate>
    <FooterTemplate>
        <div>
            <asp:LinkButton ID="SearchButton" runat="server" CommandName="Search" Text="Search">
            </asp:LinkButton><asp:LinkButton ID="ClearButton" runat="server" CommandName="Clear"
                Text="Clear">
            </asp:LinkButton></div>
    </FooterTemplate>
</asp:DynamicFilterRepeater>

This is the default template for items within the DynamicFilterRepeater and is very similar to the FilterRepeater we just deleted.  You can customize this, but you must, MUST, MUST have one and only one DynamicFilterControl with the ID="DynamicFilter" in the ItemTemplate.  The DynamicFilterRepeater container uses this to create your filtering controls.

After we have the DynamicFilterRepeater control completed, we need to replace the LinqDataSource with a DynamicLinqDataSource. The existing LinqDataSource should look something like this:

<asp:LinqDataSource ID="GridDataSource" runat="server" EnableDelete="true" EnableUpdate="true">
    <WhereParameters>
        <asp:DynamicControlParameter ControlID="FilterRepeater" />
    </WhereParameters>
</asp:LinqDataSource>

Don’t delete it.  Switch to the designer view and select your DynamicFilterRepeater and then the Actions pop-up arrow.  This will allow you to select a DataSource.  Select your target datasource, in this case GridDataSource, from the drop down list.  You will see an action called UpgradeData source appear in the Action popup, hit it.  This will automatically change your LinqDataSource to a DynamicLinqDataSource, pretty cool, huh?

Your data source should now look like this (notice the removal of the DynamicControlParameter tag!):

<asp:DynamicLinqDataSource ID="GridDataSource" runat="server" 
    EnableDelete="True" EnableUpdate="True">
</asp:DynamicLinqDataSource>

If you dragged the DynamicFilterRepeater onto the form in DesignView, it will automatically have added a reference to Catalyst.ComponentModel.DataAnnotations, if not you must add a reference.  It should be in the list under the .NET tab, otherwise browse to %PROGRAMFILES%Dynamic Data Filteringbin. 

The final step is to modify the metamodel.  Since the samples provided with the installer use the AdventureWorksLT2008 database I am going to annotate the Product class.  This is an example of the Product class and annotations.

using System;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using Catalyst.ComponentModel.DataAnnotations;
 
namespace AdventureWorks.BusinessObjects
{
    [System.ComponentModel.DataAnnotations.MetadataType(typeof(ProductMetadata))]
    public partial class Product
    {
        /// <summary>
        /// This is the Metadata for the parent Product class.  It is a private interface to prevent 
        /// consumers from attempting to instantiate it or even see it.
        /// </summary>
        private interface ProductMetadata
        {
            [Filter(FilterMode = FilterControlMode.Contains)]
            string Name { get; set; }
 
            [Filter(FilterMode = FilterControlMode.Contains)]
            [DisplayName("Product Number")]
            string ProductNumber { get; set; }
 
            [Filter(FilterMode = FilterControlMode.Contains)]
            string Color { get; set; }
 
            [Filter(FilterMode = FilterControlMode.Range)]
            [DisplayName("List Price")]
            decimal ListPrice { get; set; }
 
            [Filter(FilterMode = FilterControlMode.Equals)]
            [DisplayName("Product Model")]
            ProductModel ProductModel { get; set; }
 
            [Filter(FilterMode=FilterControlMode.Equals)]
            [DisplayName("Product Category")]
            ProductCategory ProductCategory { get; set; }
 
            [ScaffoldColumn(false)]
            Guid rowguid { get; set; }
 
            [ScaffoldColumn(false)]
            DateTime ModifiedDate { get; set; }
        }
    }
}

One thing to note in this example is that I have made the Metadata class a private nested interface of the Product class.  I have done this to prevent visibility from outside classes and also to prevent any code within the Product class from attempting to instantiate a instance of that type.  While giving a presentation last week, Scott Seely asked if this was possible, we tried it on the stop and it worked like a charm. 

Now run the solution and you should have FilterControls defined for List.aspx page template.

Posted in ASP.NET, Dynamic Data | 3 Comments »