Monday, June 23, 2008
Posted on Monday, June 23, 2008 5:02:30 PM (Mountain Daylight Time, UTC-06:00)  Comments [8] | 
Categories: Devt Tools | General

vista I was running into a LOT of weirdness with my Windows Xp installation, so I figured I'd upgrade to Vista 64 instead of futzing with another re-do of Xp.

I've been running Vista on my notebook an home workstation for about 6 months with no issues, and with my MSDN subscription, so it's a no-cost thing - just grab the disk and an authorization code, and let 'er rip.

Hardware Compatibility is one of the first things you should be concerned about when jumping to the 64-bit platform, but we had pre-planned this to some extent. When we built out our development boxes, we followed the "CodingHorror Ultimate Developer Rig" parts list. So other than the quad core CPU, I've got exactly the same box. Since Scott Hanselman has been running Vista 64 for a long time, with few issues (here's a link to his podcast on the Vista 64 Developer Experience) this should go pretty smoothly.

One nice thing about re-paving a machine is you get to clean out all the crud that accumulates over time. So, as I re-built things, I created a list of all the stuff I could not live without.

Vista Components:

  • IIS w/ IIS 6 compatibility
  • Disable User Access Control - secure, but a hassle

Development Tools:

Productivity:

  • Office Enterprise 2007
  • Visio 2007
  • Slickrun  - launcher goodness
  • FolderShare - sync folders across multiple systems
  • Notepad++ - notepad with tabs and syntax hilighting
  • FireFox
    • FireBug - must have for Ajax development
    • FoxMarks - sync bookmarks across multiple systems
    • IETab - runs IE inside FireFox - good for SharePoint

GIS:

  • ArcGIS Desktop (Editor) 9.3 Beta
  • uDig

 

So, .NET developers - what other tools do you install on a fresh box?

Wednesday, June 04, 2008
Posted on Wednesday, June 04, 2008 7:28:43 AM (Mountain Daylight Time, UTC-06:00)  Comments [4] | 
Categories: .NET | Devt Tools | Fundamentals | Unit Testing

This is the third and final part of a three part series summarizing the results of the 2008 Geospatial Developer Survey. For further information, be sure to check out read part one and part two

 

Use of Source Control Systems

This is where we start to see some divergence from the larger developer community.

 scc

Source control is as much a part of most developers lives as the language they use. It should be automatic and used by default. Subversion is good, and free. It's not trivial to setup, but with free subversion hosting services like Assembla.com, there is virtually no reason not use it. (btw - although I have an "Assembla" badge in my sidebar, I am not paid to endorse them - their service is solid and so I promote it).

Automated Build Tools

With more than half of the respondents not doing automated builds, we are seeing more of the separation from main-stream development.

autobuild-tools

All the choices on this question were .NET, but I also compiled the "Other - Please specify" results into a chart.

 autobuild-other

Unit Testing

There were 3 questions on unit testing, mainly because I see this as a key element raising the quality of GIS software projects. Unit testing is as much a philosophy about how you develop software as it is the actual writing of tests. Committing to doing unit testing really says you care about quality, and that you realize that manual testing, while valuable, is never as consistent as automated tests. So, with that we start with a look at what percent of projects are using unit testing.

Using_Unit-Testing

I don't know how this stacks up to other industries, but I'd say there is room for some growth here. Everyone talks about GIS getting on the "service bus", but we need to make sure that when we get on the bus, our code does not fail!

The next question basically asked why you were not doing more unit testing.

why-not-unit-testing

This is actually pretty good. I'd have to question the 14% who don't think it's valuable, but I'll chock that up to them not knowing what's really involved.

I've heard the "not-enough time" thing before, but the problem is that you will have bugs. And someone will find them. Better the developer finding them sooner than a client finding them later. Also, in terms of time, on big projects, I think you actually save time.Having automated tests, helps you prevent regression. Think about all the stuff that breaks between a big ArcGIS releases - that's regression, and that's what good automated tests can catch.  

Difficulty. This is true. Writing good unit tests is hard. Using good design patterns help, and good tools can ease the pain, but even still it's not easy. Writing unit tests for ArcObjects code is very difficult, but not impossible. In these cases, I focus the tests on the most critical parts of a system - basically putting the effort where it will payoff the most. For these areas, I shoot for 100% code coverage - if they are the most complex, I want to make sure that my tests cover all possibilities. Again, difficult, but if you are writing a complex spatial rule engine, that works with relationships between multiple layers, business workflows, and user permissions, there is no realistic way to manually test it on any sort of a regular basis.

The next question was "If tests were easier to write, would you write more of them?"

unit-tesing-easier

So, a resounding YES on that. This is great, because as a community we can actually make this happen. 

A couple years back I threw some code out there under the umbrella of "ArcUnit" - the files referenced in those posts are now gone, but it was some demo code that showed how to unit test geometry operations, by serializing geometries and storing them in the unit test assembly. The code is now on Assembla in the ArcDeveloper project, under TestingUtilities. Seeing as there is interest in this, I'll likely write some more articles on this.

Unit Testing Frameworks

Ok - the Java people really ripped on this question. After adding an "Other", I did tabulate the results for all that as well.

unit-testing-frameworks

This gets somewhat interesting - 60% of people said they are not using any tools, but back in the "What percent of your projects use unit testing" only 38% said "None". I guess some "homegrown" unit testing could explain a few percent, but... anyhow. Interesting that MBUnit and MSTest are so low. MSTest is baked into Visual Studio 2008 (Professional and above), and MBUnit is both free and awesome.

As for the "other", here's how that stacked up.other-ut-frwk

Apparently I could have saved myself a heap of greif if I'd just added jUnit to the list!

The final Unit Testing question went out to the edge - "What do you think of Test Driven Development"

tdd

So at least one zealot in the crowd aims pretty high! For the "No opinion" crowd, TDD is the practice of writing your unit test before the implementation. The intent of this is to essentially define the desired behavior in the test, then make the software behave in that way. No doubt this is difficult, and requires you to be a total unit testing & pattern guru. I *think* this is possible, even on complex projects like GIS, but you'd need to be working with a test friendly GIS framework (as in don't come asking me to build you an ArcGIS Server .NET ADF site using TDD!)

 

Code Refactoring

As you write code, there are times when you need to change it's structure - usually to conform to a pattern, to facilitate extensibility, or just because your function got long and messy (i.e. you're making maintenance easier!). This is called refactoring. The first question was related to how often you refactor your code.

refactoring

The second question related to the use of .NET Refactoring tools. I appologize again to the non-.NET people, but I don't know of any Java Refactoring tools.

net-refactoring

What's interesting here is that the "Not Refactoring" people are not even using the tools in Visual Studio. When we were doing a lot of desktop development, we used RefactorPro - mainly because they had good Visual Basic.NET support. Now that we're using C# and doing 99% web development, we are finding that the IDE tools / manual refactoring is sufficient.

Code Documentation Generation

This was a quick question on the use of automatic code documentation generators. They are pretty common in the larger developer community, and relatively easy to bring into the mix, and spit out some good API documentation. Worth the effort in my opinion.

doc-tools

 

Comments

Fifty-Two respondents left comments at the end of the survey. Most were constructive, and others... well... lets look:

WTF, no C++ on the list of languages? What language do you think the bulk of geospatial software (from GDAL to ArcGIS) is written in? C# is just a evil marketing ploy from MS to try to deflate Java's market; nobody is expected to actually _use_ C#.

Reply: Not having C++ was an oversight. As for your issues with C#, can't help you there.

Summary:

Overall, this was an interesting experience. Clearly I could do a much better job on the questions, and have a much wider range of options on the answers. I think it does show that geospatial developers are adopting main stream techniques and tools, just at a somewhat slower pace. Thoughts?

Download the results (Excel 2007 format)

Friday, October 05, 2007
Posted on Friday, October 05, 2007 9:21:56 PM (Mountain Daylight Time, UTC-06:00)  Comments [1] | 
Categories: ArcGIS Devt | Devt Tools | Unit Testing | Visual Studio 2005

I just finished off some burly refactoring of our security management code base so that it could be better unit tested. This subsystem essentially controls what tools a user has access to, as well as what layers / features a user can edit, so it's a pretty critical part of the infrastructure.

I'm working on some posts about how I did this, and should get them out next week, but for now, I'll just show this...

tests

Although there are only 16 tests listed, many of these methods actually contain a number of individual test assertions, and there are more than 80 tests that are actually run.

Thursday, September 20, 2007
Posted on Thursday, September 20, 2007 2:26:59 AM (Mountain Daylight Time, UTC-06:00)  Comments [0] | 
Categories: .NET | ArcDeveloper | Devt Tools

I'm in the process of creating a set of Visual Studio templates to share with the community - pretty simple stuff, but can be quite a time saver. In the past I've posted about how to streamline coding using templates, and while the process for packaging templates outlined in that post works, it's pretty manual, and that's not going to work if I'm going to maintain and grow these things. Enter MSBuild. But before I go into that, lets review how I've organized the solution.

The solution is called "ArcDevelper.Templates" - and it simply contains a bunch of other projects that contain the template files, as shown in the following graphic.

Template Solution Contents

Each project simply has the template file (class.cs for example), an associated icon, and the vstemplate file that tells Visual Studio how to transform the file. It's important to note that I'm are just using Visual Studio as an editing environment, and the solution as an organizational scheme - we do not actually "build" anything in the traditional sense.

First off the projects would not compile because the still have string parameters in them that get replaced when the templates are run (see my previous post on templates for more). What we want to do is package the files so they can be used as "templates" - this is where MSBuild comes in.

The MSBuild Script

The other thing I have in the solution is a build.xml file that actually extracts out the files, puts them into zip files and moves them to my "ItemTemplates" folder. With this in place, I can easily make changes to my templates, re-run the build script, and have the updated templates immediately available.

In order to make this work, I had to use MSBuild "batching", which is not exactly intuitive. Without getting into too much about MSBuild (Google it - there's ton's of info around), when creating the itemgroup that will be fed into the target (the actual zip & copy), you need to create some metadata for the items, and then use the Outputs attribute of the Target to subset the items by some of the metadata. As an old client of mine used to say - clear as mud. Maybe this will help...

  <ItemGroup>

    <Projects Include="$(SolutionDir)\csclass">

      <path>$(SolutionDir)\csclass</path>

      <zipname>CSClass</zipname>

      <itemname>Class</itemname>

    </Projects>

    <Projects Include="$(SolutionDir)\vbclass">

      <path>$(SolutionDir)\vbclass</path>

      <zipname>VBClass</zipname>

      <itemname>Class</itemname>

    </Projects>

  </ItemGroup>

This is the Item Group that lists the templates (projects) that we will be working with. The path, zipname and itemname sub-elements are the metadata I was talking about. This is then used by the target...

  <Target Name="Build" Inputs="@(Projects)" Outputs="%(Projects.ZipName)">

    <!-- Create a list of the files in the output folder-->

    <CreateItem Include="%(Projects.path)\%(Projects.itemname).*">

      <Output TaskParameter="Include" ItemName="FilesToZip" />

    </CreateItem>

    <!-- Zip the files-->

    <Zip Files="@(FilesToZip)" ZipFileName="$(BuildFolder)\%(Projects.zipname).zip"  Flatten="true"/>

  </Target>

The target specifically notes the inputs and the outputs. Apparently by specifying a metadata item in the outputs forces MSBuild to group / subset the items (depending on how you want to think about it) by that item. In my case, the item is unique - so I get the effect of simply looping over the list.

Anyhow - now I've got this all working smoothly, so I'll add some more stuff into the templates, and then load it up into the ArcDeveloper.net Subversion repository over at SourceForge. I'll post about the actual templates when they are up there.

Sunday, August 05, 2007
Posted on Sunday, August 05, 2007 10:47:45 PM (Mountain Daylight Time, UTC-06:00)  Comments [1] | 
Categories: Devt Tools | Team System

This week I will be transitioning from Microsoft Team System to Subversion for our source control system. There are two main reasons for this change - cost and ease of use.

Cost

The cost issue is two fold - first there is the internal cost of using the Team Editions of Visual Studio. For the MSDN subscription, Team Edition (not Team Suite) runs $1000 more per develper, per year than Visual Studio Professional. While this is not bad for a small team, it's prohibitive if you are looking at growing significantly, or standardizing across large group. I can think of many useful ways to spend $7,000 per year besides sending it to Microsoft. Not that Team System is not cool and useful, but in the end, I just don't see it being $7,000 per year cooler than Subversion + TRAC (open source issue/bug tracking system) and that's the real bottom line - value. 

The second cost aspect is somewhat inverse - if we are using Subversion and an open source build/unit testing/coverage/installer stack, then we can ship this to our clients. Since we build state level enterprise systems, and most of our clients expect to take on the longer term support and maintenance of the system, there is some serious value in being able to turn it all over to them as a comprehensive development platform. If we are on Team System, then it would be doubtful if we could ship the whole stack.

Ease of Use

Since Team System is fully integrated into Visual Studio Team Edition, the user experience for most things is pretty good. Actually I really like the check-in rules you can implement. However, we have had many issues working with web projects, as well as dealing with "other" files such as CodeSmith templates. Of course CodeSmith does not "know" about Team System, so it can't automatically "check out" the files prior to editing them. Since Team System sets your working copy to read-only when you check in (there may be a way to change this - not sure), in order to make a change to my template, I need to open Visual Studio (slow), connect to Team Server (slow), navigate to the templates in source control, check out the file, make the change, go back to Visual Studio and check in the file again. Compared to working with  Subversion, this is a major pain.

The Transition

At this point we have our Subversion server setup, and our domain accounts are authenticating through Apache. All is well. The next step is at the end of our current Sprint, get the latest code from Team System, do a build, run all the tests, clean the solutions (using Omar Shahine / Jeff Atwood's Clean Sources) and then load the files into Subversion. I did some Googling for tools which would take the history etc. along for the ride, but I did not find anything. At this point we are early enough in the project where losing history would not be too much of a problem, and we'll be able to have the Team Server running for at least 6 months incase we really need to get some old version.

Tools

At this point we are planning on using the very well regarded TortoiseSVN as the main client for Subversion, but we'll also be trying AnkhSVN and VisualSVN to handle the Visual Studio integration. I'll let you know how those tools pan out.

Monday, June 11, 2007
Posted on Monday, June 11, 2007 10:00:28 PM (Mountain Daylight Time, UTC-06:00)  Comments [0] | 
Categories: .NET | Devt Tools

One way to increase developer efficiency is to leverage automation where possible, including in your Visual Studio item templates. In this post I will review how to create some simple Visual Studio templates, and how to share them with a team of people. 

About Item Templates

For every type of item you can create in Visual Studio, there exists a template, and when you select the item to add to your project, the template gets executed, the new item is produced and the file(s) are added to your solution. Sounds simple, and for the most part it is. Of course there are some wrinkes.

Before we get into that, you can find your existing templates at:

C:\Program Files\Microsoft Visual Studio 8\Common7\IDE\ItemTemplates. There is also a ProjectTemplates folder at the same level. Templates for each language (Visual Basic, C# etc) are located below these folders.

Zip Files and the Template Cache

The first wrinkle is that templates are stored in zip files. The second wrinkle is that the actual templates that are used by visual studio are stored in a cache folder. This is located in the same folder, and not suprisingly named ItemTemplatesCache.

This is all well and good, but it can make debugging your templates a little bit of a pain.

Editing Templates

The first thing to do is decide where you want to actually edit your templates - I would not edit them in the ItemTemplates folder. Since these end up being part of your codebase, create a source controlled location just like you would for any other code. 

Custom Class Template

In this example I'm going to show how to add some useflu extras to all your classes. We'll add a header that will have a copyright statement, the developer's name and the date it was created, as well as a default namespace. To do this, in Visual Studio, we just create a new class library project, and add a class. We then edit the class so that it has the header we want, and the regions.

We also need to add some parameters into the class that Visual Studio will replace when the item is added into the solution. These are of the form $parameter$, and there are 13 that are automatically present. You can also create custom parameters if you need more control. See the MSDN page on Template Parameters for more information.

Option Explicit On

Option Strict On

'======================================================

' Copyright Statement...

'======================================================

' Author: $username$

' Date Created: $time$

'======================================================

' Description:

'

'======================================================

#Region " Includes"

 

#End Region

 

Namespace YourDefaultNamespace

 

    Public Class $safeitemrootname$

 

 

    End Class

 

End Namespace

Icons

If you want your new class to have a saucy new icon, then you'll need to create or locate a suitable icon and have it handy when we export the class from the project.

Exporting to a Template

Once yoiu have the file the way you like it in Visual Studio, simply use File --> Export to Template to start the export Wizard. The wizard is very simple and easy to follow. What's really nice is that you can have the template automatically include references into the target project for you. This is very convenient when working with ArcObjects.

The final step of the wizard is shown below - essentially it will export the template, create the vstemplate metadata file, store the output and import it into Visual Studio all at once.

Using the Template

Once the template has been imported into Visual Studio, it's ready to be user. Just add an item to a project, and scroll down in the "Add New Item" dialog to the My Templates section. There you will see your shiny new tempalte.

Select it, give it a name, and Visual Studio will do the replacement, and open it in the editor.

Option Explicit On

Option Strict On

'======================================================

' Copyright Statement...

'======================================================

' Author: Dave

' Date Created: 06/11/2007 21:46:32

'======================================================

' Description:

'

'======================================================

#Region " Includes"

 

#End Region

 

Namespace YourDefaultNamespace

 

    Public Class SomeNewClass

 

 

    End Class

 

End Namespace

That's it. You now have a way to easily create classes that have consistent headers and organzaiton. This is a very simple example, but you can look at the ArcGIS templates provided by ESRI and see some examples doing more complex things.

Sharing Templates

It's  one thing to write your own templates, but the real benefit shows up when you have a whole team using the same templates - this ensures that the code is more consistent, and thus it's easier for other team members to work on. Sharing templates  is a two step process. First, put your shared templates on the network, and use the Tools --> Options, Projects and Solutions and set the location of your User Item templates. Next, open the Visual Studio Command Prompt (not a normal command prompt!) and run devenv -installvstemplates. This copies all the templates from the User Item Templates location into the ItemTemplate cache. Whenever the templates are changed, this step must be re-run to load the items into the local cache.

In a following post I'll show some more complex templates that simplify the Supervising Controller pattern I talked about a few posts back.

Download the example Template Visual Studio Project You'll have to export the template after editing the custom class - i.e. adding your copyright and default namespace!

Resources

Template Parameters (MSDN)

Visual Studio Templates Overview (MSDN)


Tuesday, March 06, 2007
Posted on Tuesday, March 06, 2007 2:17:05 PM (Mountain Standard Time, UTC-07:00)  Comments [0] | 
Categories: Devt Tools | Software
A while back I posted about setting up my home source control server using Subversion. The original post basically listed the steps to getting it installed.

I was just reading Omar Shahine's blog, and he noted that there is now a 1-Click Subversion setup package for Windows users. I had not heard about this, and thought I'd point this out to others. Installing subversion was pretty simple before, and now it's virtually painless.


So - if you still have a list of reasons why you were not using source control, you can strike out "difficult to install" and "cost".

Monday, October 30, 2006
Posted on Monday, October 30, 2006 9:45:10 AM (Mountain Daylight Time, UTC-06:00)  Comments [2] | 
Categories: ArcGIS Devt | Devt Tools | General

Since we are hiring, we need to get some more workstations - thus it is time once again to see how much power a couple of grand will buy. If you have recently bought a kickin workstation for ArcGIS Development - I'd love to hear about your experiences...

Planning

Instead of simply specing out a top end box without much idea as to how it would perform, I decided to try and figure our what ESRI would recommend. I started by cracking open the 2006 System Design Strategies white paper from ESRI. I say cracking, but really it was quite a bit of waiting as Acrobat loaded the 289 page document.

Here's the important bit - on page 7-17, the document states that ESRI uses the "SPECInt Rate 2000" as their system comparison benchmark. Conveniently the rates for all kinds of systems are published so you can check things out.

After further digging in the system design document, it turns out there was little in there that I could directly apply to the developer experience i.e. they have not done benchmarking for how fast ArcMap starts, or how fast visual studio is while debugging. So, I decided to check the rating on our current systems, so I'd at least have a relative ranking.

Current Workstations:

Dell Precision 370, 3.8Ghz P4 w/ hyper threading, 3GB RAM, 256Mb dual head video card, ~100GB disk

While not specifically listed, a similarly equipped Acer system with this chip rates a 23.5

While not bad, these workstations certainly could be faster - particularly when starting ArcMap, and running Visual Studio 2005 with large solutions. Thus, I started looking at systems which had a higher Spec rating, and more specifically at the CPU's which had the high ratings.

AMD Athlon vs Intel Core Duo

Obviously there are other factors which make a PC fast, but at the heart of it all is the CPU, so may as well start there.

The top rated AMD chip is the Athlon 64 FX-62, with a 43.7

The top of the heap from Intel is the Core 2 Extreme X6800 at 63.5 with other Core 2 Duo's coming in at 58.7 (E6700) and 53.7 (E6600). Based on this, I figured that we should be able to at least double our workstation performance. The next step was figuring out what is was going to cost.

Looking for Systems

Traditionally we've been a Dell shop, so I started there.

The Dell Precision 390  can be configured with each of the Core 2 Duo chips. For the pricing below, all have 4GB of DDR2 RAM, and 2 80GB harddrives, 128Mb dual head video card, CD/DVD burner WinXp. (For those scratching their heads on the 80GB drives - we really don't need a lot of disk space, as 90% of our projects use ArcSDE as the data store.)

Here are the prices (as of 10/27/06)

  1. Core 2 Extreme X6800: ~$2800 (Spec 63.5)
  2. Core 2 Duo E6700: ~$2350 (Spec 58.7)
  3. Core 2 Duo E6600: ~$2150 (Spec 53.9)

Not bad, but last winter I built a box for home and I've been really happy with it, so I thought I'd check out what I can get from there - GlobalComputer.com.

They have a Systemax system that's build to order - same basic config - 4GB DDR2 RAM, 2 80GB hard drives, 256Mb dual head video card, CD/DVD burner, Win Xp.

  1. Systemax Core 2 Duo E6700: ~$1950 (Spec 58.7)
  2. Systemax Core 2 Duo E6600: ~$1650 (Spec 53.9)

Verdict?

It's hard to say - Dell does have great support, and it's the exact system noted in the Spec ratings, so that's a bonus. That said, is the support really worth the $400-$500 difference? An even better question relates to the cost difference vs. performance difference between the top $2800 system (63.5) and the much cheaper $2150 system (53.9). Is that 10 spec points really worth $650? Or is there just a premium on the fastest chips?

We'll have to make the call next week, but right now, I'm leaning towards the Systemax boxes. We've had great luck with other off-brand boxes (1/2 our servers are SuperMicros) and I'm sure that I can find some other cool stuff to get with the remaining cash.

Friday, September 29, 2006
Posted on Friday, September 29, 2006 12:54:40 PM (Mountain Daylight Time, UTC-06:00)  Comments [3] | 
Categories: .NET | Devt Tools
After last nights ArcDeveloper talk on code generation with the Geodatabase (link to powerpoint slides ~5Mb), I ran into a blog entry on Microsofts "Data Access Guidance Package" by David Hayden over at CodeBetter.com

From my quick read, the "Guidance Automation Toolkit" contains a set of tools for creating data access layers via code generation, automation tools  and templates for use in Visual Studio, as well as recipes (the "guidance" part) for how to apply all this. Sounds nice.

But, being Microsoft Labs, they take it a step further - there is also a "Web Service Software Factory", which is designed to work with the output of the Data Access Guidance Package.

Armed with these tools a developer should be able to go from a data model to full set of business objects to an operational web service in an afternoon. That's power.

If this sounds good to you, check out these articles... (also David Hayden)

Get the bits here...

 

Friday, September 01, 2006
Posted on Friday, September 01, 2006 11:52:20 AM (Mountain Daylight Time, UTC-06:00)  Comments [0] | 
Categories: .NET | Devt Tools | Fundamentals | Software
I just saw Rob Howard's posting - Build it quickly, use it as soon as possible and make it simple - about the evolution of Telligent's development philosophy. For those who are not famlilliar with Telligent - they make Community Server, which is used on a lot of sites, including ArcDeveloper.net

I like is take on the agile mantra of "Release Early and Release Often"  - rather than release, if possible start using the software prior to release. This will help you identify usability and stability issues early. Then get it out the door as fast as possible.

Rob makes a couple really good points:
One of the biggest lessons we've learned is one we didn't really anticipate: a shift from caring less about the underlying technology to how our software solves the user's problem...

... our philosophy is: (1) build it as quickly as we can (2) start using it as soon as possible (3) make it simple.

For consultants or small software companies, this is right on the mark and critical to success - focus on making the users life easier, and create the simplest solution that can work. If it's successful, evolve it from there. If not, then you don't have too much investment.


It's also worth noting that (from what I can tell anyhow) this is more or less the approach of Google these days.

Posted on Friday, September 01, 2006 11:04:11 AM (Mountain Daylight Time, UTC-06:00)  Comments [2] | 
Categories: .NET | ArcGIS Devt | Devt Tools
Now that we've got our geodatabase data access layer as objects, it's time to leverage them - by letting Visual Studio create and wire up data forms directly from our classes.

Since we now have native .NET objects to work with, we can use Object Data binding. Object Data Sources basically extend the .NET 1.1 data source / data binding story to allow direct binding to business objects. What's really cool is dragging a class onto a form and watching visual studio layout and wire up the whole UI. Here's another screen-cap walk through...

Step 1: Create a winforms project and add a reference to our code generated class library. In the winforms project, create an Object Datasource which points to a class in the class library. In this case, it points at the "Forest_Stands" class.



Step 2: In the Data Sources window, you specify the controls you want rendered on your form for each property. For simple types, visual studio picks the right control. For complex types (i.e. Domains), I created a custom control, and that's what's selected in this next image.


Step 3: Drag items from the Data Sources window, onto the form. I'm not doing any manual work here - just dragging the class that I code generated from the database, onto the form, and Visual Studio handles the rest.

Blank Form

Drag the "Forest Stand" class onto the form...


Visual Studio builds out the UI. And it's data bound. Let's drag out a data grid of related items. The relationship between the Forest Stands class and the "Stage 1 Canopy" table was extracted from the Geodatabase model, and implemented in the generated classes.




Now we run it.



The form is now data bound to the feature and object classes stored in our geodatabase, and I wrote all of 10 lines of code in the UI. We're still working on adding in custom DataGridView columns which will correctly handle range or coded value domains, but that should be wrapped up in the next week or so.

Tuesday, July 25, 2006
Posted on Tuesday, July 25, 2006 9:25:28 PM (Mountain Daylight Time, UTC-06:00)  Comments [2] | 
Categories: .NET | ArcGIS Devt | Devt Tools | ESRI
Jeff Germain and I have been doing some cool work with the geodatabase, and I'm going to summarize our work over a series of postings. This post introduces the key ideas...

Standard "Business Objects"
In keeping with object-oriented design, most applications are now utilizing classes (business objects) to represent the real-world entities of concern to the application. When it comes time to store these entities in a database, the data access operations are typically bundled into the business objects themselves, or in associated helper classes. The advantages of this model are many, including:
  • cleaner code design
  • easier maintenance
  • encapsulation of data storage logic
  • single point for database schema changes
  • with .NET 2.0, object data binding is possible (very cool)
There are many design options which take this model to various levels of complexity. You can find all sorts of information about Object Relational Mapping at ORMappers.com

Geo "Business Objects"

Since this is such a nice design pattern, we wanted apply the same logic to the geodatabase. Afterall, you design classes when you design a geodatabase, but the geodatabase API is cumbersome as compared to working with standard business objects. 




To be clear - we're not talking about replacing IFeature and IRow, after all, you still need to talk to the geodatabase, and that's how ArcObjects works. But, in order to avoid working with the geodatabase API all over our code, we designed wrapper classes that hide the ArcObjects code behind a nice "business object" facade.



Some might ask - why would you go to all this trouble? The first part is that for large enterprise systems, where they may be 10 or more associated attribute tables related to one feature class, being able to work with a set of business objects greatly simplifies creation of attribute editing forms. And, if designed correctly, these objects could be used in Desktop, Engine and Server applications. The second part is that once you set it up, it's not much work. Which brings us to...

Code Generation
A nice thing about business objects is that they follow a pattern. And computers can do great things with patterns - like write the code for us. This is what code generation tools bring to the table. A typical code generation tool connects to the database, reads the schema, and creates classes based on code templates. This process takes a few seconds, and can be re-run at any time, and many teams add this as a step in their build process. Depending on the templates used, there are options where the developer can add custom logic which is not over-written when the code is re-generated (via inheritance or partial classes). As you may have guessed, this results in massive time savings when writing applications.



For example, I needed to create an application to edit the tables in a standard relational database (Process table shown above). Using RapTier, I was able to create a complete data access layer in a few minutes. Once that part was done, I was able to very rapidly wire the business objects into an interface, and the application was complete. The image below shows the classes created for the "Process" table. You'll notice that these objects do not have "Get", "Save" or "Update" methods. In the abstration model used by RapTier, all these functions for all the classes in the database are in a single helper class.



But this is a Geodatabase...
So, this works well for traditional RDBMS tables, but it's not going to fly for the geodatabase. First off, you can't infer all the details of a geodatabase model directly from database schema itself. Specifically, you'd miss thinks like relationships, domains and subtypes. Additionally, if you are working aginst ArcSDE you'll get all those pesky A, D, F, and S tables. Finally, the code that would be generated would use standard SQL (or stored procs) to insert and update the data. So, clearly we had some issues to work out.

Our Process
We've got two large projects on the go right now, and both are going to be subject to many geodatabase schema changes over their life span. To that end, we are working on a process where by we are able to generate business objects (and class extensions) directly from a geodatabase. The diagram below shows how this works, but the high-level steps are as follows:
  1. Export the geodatabase schema as Xml
  2. Transform that into a simplified Xml
  3. Use this simple Xml to generate the code
  4. Use object data binding in .NET 2.0 to simplify the form wiring
  5. Repeat when the schema changes



In the next installment, I'll review the process, the business object templates we've created and tools we've used to so this.
Monday, March 20, 2006
Posted on Monday, March 20, 2006 8:03:35 PM (Mountain Daylight Time, UTC-06:00)  Comments [0] | 
Categories: ArcGIS Server | ArcIMS | Devt Tools | ESRI
Made if back from Palm Springs just in time for a big old Front Range snow storm. Right now its dumping in Fort Collins. Other bloggers have already posted great information from the second day, so I'll not re-hash that - just link over there - James Fee, Rob Elkin, Cory Eicher.

My Additions:

First - a big kudos goes out to Brian Goldin and everyone else at ESRI who made this conference possible. In 10 years of attending conferences, this was by far the most useful conference.

Next - What can you say about the .NET ADF! Big big props to Art Haddad and his team for making all our lives easier (when it's released). We're already scheming up projects where we can use the ADF. Who says ESRI is not raising the bar? For those not in the beta program, and who did not attend, just wait! Web mapping elements are no-longer second class citizens grafted into otherwise industry standard web-sites. Expect seamless integration of mapping into any .NET 2.0 web site when this rolls out.

Ideas for next time:

Software Enginnering Practices
As someone noted in the closing session -  some sessions where ESRI talks about their best practices re: software engineering process. Many GIS developers do not come from a Computer Science background, and may not work in shops where source control is taken for granted, and having good unit tests is as important as having good code.

Real-World Applications
Sessions which show real-world applications - co-presented by ESRI and the developers would be very cool. This would inject the dirty reality in which all problems can not be solved at the coarse-grained level.

Fine-Grained Love
And - as echoed by many attendees - we love our fine-grained objects. So sessions on that would also be great. Just to kick a topic out there - "Best Practices for working with IGeometry". This would be particularly good because there are so many ways to interact with the low-level geometry objects, and some are much faster than others (geometry bags vs iterating over a collection). Add into that the "zen" of dealing with precision differences between the map frame and a feature class, and how that effects operations, and you'd have a weighty 75 minutes of fine-grained love.

Back to reality and some non-ADF ArcGIS Server work.

Saturday, March 11, 2006
Posted on Saturday, March 11, 2006 6:57:48 PM (Mountain Standard Time, UTC-07:00)  Comments [0] | 
Categories: .NET | Fundamentals | Devt Tools
Developer Fundamentals: Refactoring - Keeping your code simple
Unit Testing and Refactoring are tightly inter-twinded, as unit tests can be used to ensure that your newly refactored code still runs, and once your code is refactored, it's easier to write tests for. But I'm getting ahead of myself - let's start at the beginning...

What is Refactoring? (from Wikipedia...)
Refactoring is the process of rewriting a computer program or other material to improve its structure or readability, while explicitly keeping its meaning or behavior.
Refactoring is simply re-organizing your code to make each function as simple as possible, while still retaining the same overall functionality of the system. Many times this means simply breaking up large complex functions into smaller simpler functions. Thinking in objects, this tends to mean one of two things: breaking a large multi-purpose object down into simpler single-purpose objects, or creating multiple private (internal) functions which are used by a public method. The image below shows this graphically.
 


There are multiple benefits of this: code that is simple, is easy to read, which means its easy to maintain. Keeping classes simple also increases the probability of re-use, and makes it easier to test. And if you're going to bother re-using code, you want to make sure it's well tested, which brings us back to Unit Testing. Ah, the circle of life!

It's very common to see large complex functions in ArcObjects code. I believe that this is due in part to how the developer thinks about the problem - as a linear series of steps. Maybe this is a throwback to AML? When writing code, they just follow the linear steps as one big function. While this can work, the down side is that it's very difficult to test the parts of the function, and it's very very difficult to re-use portions of the code without copy-pasting (a very common, yet bad practice because you now have two places where you need to maintain code that is similar or the same).

Thus, I highly suggest adding refactoring to your coding practice. It can be done manually, but all the copy pasting & renaming can be somewhat time consuming. Luckily, there are tools to help out. If you are using Visual Studio 2005, there are built in refactoring tools for both VB and C#. For Visual Studio 2003, there are a variety of third party tools which can help simplify the job. For detailed information on refactoring you can check out Refactoring.com.

Happy Coding!
Wednesday, February 15, 2006
Posted on Wednesday, February 15, 2006 7:01:12 PM (Mountain Standard Time, UTC-07:00)  Comments [0] | 
Categories: .NET | Devt Tools | Fundamentals
Time for another dose of developer zen. This time I'll try to take a quick look at OOP (object oriented programming) and some issues which can occur if you are transitioning from procedural languages (AML) or pseudo OOP languages (VB6 & Avenue). To start with, I think it's worth noting that just because you are using an object oriented language (Java,C#, VB.NET etc.) does not mean you are writing / designing your code in an object oriented manner. I think this may be an afront to some people, but it's just the truth. You can write procedural code in any OOP language. And it can work. But there's just so many reasons not to.
In this article, I am simply listing 3 things you should try to avoid. For more detail on Object  oriented programming, hit Google. Of course, you can ignore these warnings, but if you have to try to maintain or grow your code, you will run into problems.

Design As You Code
This is also known as "no design", or hacking. Honestly, if you ever take anything away from this blog, I hope it is this: Always design before you code. The level to which you take this typically depends on what you are doing. If it's a quick one-off VBA script to rename a set of files, then just jotting down a bullet list of "requirements" is enough. If you are trying to create complex workflow managment system for a diverse set of users, you may have several 1000 pages of requirements. In either case, having a design is critical, if for no other reason that it can tell you when you are done (i.e. all requirements are met). At some point I'll post about our design process, which tries to do "enough" design without going crazy with UML, but that's a little past the fundamentals.

GIS Data Objects "Special"
Many times I'll see code where the developer has used objects for all kinds of things, but when it comes to the actual GIS datasets (feature classes etc), they are alway treated differently. It's important to understand that in most cases, you can use these types just like any other types (string, int, arraylist etc). The reason we model things as objects is that there is some inherent relationship between them. And if one of the items that particpates in the relationship is a featureclass, then add it as a property of the class. Granted, you're not going to be able to serialize the class out to an XML file and expect the featureclass to go along, but you can work around those cases. The point here is to not be shy with these things. It's also a departure from typical GIS thinking, which can be hard for people just beginning to make the shift.

Side Effects (or Why Globals are Evil)

Unlike special effects in movies, these are bad things to encounter. A "Side Effect" occurs when something effects the internal implementation, in a way which is not expected. The end result is code which may "look" correct, but acts incorrectly in certain situations. The code below show a pretty contrived example. It has a property "ShoeSize" and a method "Add". Add takes two integers, and returns an integer. The developer would expect that add would simply return the sum of the two numbers. However, if ShoeSize is set, it returns the sum of the two numbers plus shoesize.

    1 Public Class SuperClass

    2 

    3     Private _shoeSize As Integer = 0

    4     Public Property ShoeSize() As Integer

    5         Get

    6             Return _shoeSize

    7         End Get

    8         Set(ByVal Value As Integer)

    9             _shoeSize = Value

   10         End Set

   11     End Property

   12 

   13     Public Function Add(ByVal firstNumber As Integer, ByVal secondNumber As Integer) As Integer

   14         Return firstNumber + secondNumber + _shoeSize

   15     End Function

   16 

   17 End Class



This is a very extreme example, but I think it shows the general idea. The method Add does not indicate that anything else is involved, yet in some cases (ShoeSize != 0) it will return an unexpected result, which will be very difficult to track down. A very common way to end up with a mess of side effects is through the use of "global" variables. In this case, a the variable gets set in one place, and then used in some other location which is not apparent to the developer. These sort of problems are really tough to track down. I've seen projects where it cheaper and faster to delete the application and start again rather than trying to sort out what was going on. Good Luck!

Posted on Wednesday, February 15, 2006 6:58:54 PM (Mountain Standard Time, UTC-07:00)  Comments [0] | 
Categories: Devt Tools | Fundamentals
While reading Jackie Goldstein's blog on .NET and "stuff", I saw these two free eBooks which would be good reading for the ArcObjects developer community.

Descriptions are from the APress Site...

COM and .NET Interoperability
COM and .NET Interoperability provides a complete overview of the process of building .NET applications that interact (interoperate) with existing COM code. Before digging into that critical topic, author Andrew Troelsen offers a concise overview of the COM architecture and provides examples using various COM frameworks (C++, ATL, and VB 6.0) as well as the core .NET managed languages (C# and VB .NET). After covering the preliminaries, the book explores numerous issues that arise in interoperability, including interacting with the Win32 API, dynamically generating source code via System.CodeDOM, creating serviced (COM+) components using managed code, manually editing (and recompiling) .NET metadata, and the process of constructing custom COM/.NET conversion utilities. Both intermediate and advanced developers will welcome the practical information they need to quickly work with COM and COM+ in .NET applications, and learn how to create .NET components that are COM compatible.
It's 792 pages, which is pretty weighty, but if you want to get some indepth coverage of this topic, it sounds like a good starting place. I'm not a huge fan of "reading" a PDF "cover-to-cover", but you can't beat them for searchability.
Direct Download Link (6.36 MB PDF File)

Programming VB .NET: A Guide For Experienced Programmers

In Programming VB .NET: A Guide for Experienced Programmers, authors Gary Cornell and Jonathan Morrison carefully explain the exciting new features of Visual Basic .NET. Since VB .NET is, for all practical purposes, a whole new language even for the most experienced Visual Basic programmers, developers need to think differently about many familiar topics. Cornell and Morrison are there to help you with careful discussions of each topic. All experienced programmers wishing to take advantage of the amazing new powers of VB .NET will benefit from this book’s careful treatment of fundamental topics, including inheritance, interfaces, and exception handling, as well as all the powerful new features, such as stream-based I/O and true multithreading. Cornell and Morrison write from the point of view of the experienced programmer, with constant references to the changes from earlier versions of VB. Developers learn how to use VB .NET for database programming through ADO.NET and web programming through ASP.NET. After reading Programming VB .NET: A Guide for Experienced Programmers, developers will have a firm grasp of the exciting new VB .NET language and its uses in creating powerful .NET applications.

This book would dovetail really nicely with the Fundementals series I've been posting. If you've got a background in programming, and are moving into VB.NET, this sounds like a good bet.
Direct Download Link (4.9 MB PDF File)

There are 6 other free books at the APress Site.

Saturday, December 17, 2005
Posted on Saturday, December 17, 2005 7:15:44 PM (Mountain Standard Time, UTC-07:00)  Comments [0] | 
Categories: .NET | Devt Tools

Recently I've been working with a data access layer that I did not write, and thus did not know very well (To tie this to "Arc" Development, this DAL stores ArcIMS map service settings and user permission in a database). This led to a certain level of enlightenment re: using strongly typed collections. Basically, my lack of background knowledge about the class model left me confused as to the "type" of objects which should be in various collections, thus leading to some head scratching while debugging.

A little background so we're all on the same page - a strongly typed collection is basically a collection which only accepts a certain type of object. As opposed to a generic collection, i.e. ArrayList, which can hold any type of object. The upside of using a strongly typed collection is two fold: first, you get intellisense in the IDE telling you that the collection takes objects of type X. Second, the compiler will catch any place that you ignored the intellisense. Any errors the compiler can catch is an error you won't have to debug later. Very good.

So why not use them everywhere? Basically, they are a pain to write (inherit from collectionBase, implement a bunch of stuff etc etc), and since there were few users of my APIs, and my class models are inherently brialliant and totally obvious (I wish!), using an arraylist was suitable. Now that I'm on the "consuming" end of someone elses API, I see the value, and want to update the code, but how to get around all that nasty coding? Code Generation!

Jeff turned me on to SharpTools from Morrison Schwartz (free!). This has a typed collection builder in it. For that alone you should get it. It also has other cool functions like an RSS aggregator, a code library tool, a bunch of database tools and a Google search tool. All excellent. If you don't already have this tool, download it now.

As soon as I added in the first strongly typed collection, the compiler caught 3 errors where I was stuffing the wrong object into the collection. So, next week, I'll be converting all the rest of the collections in that API over, and continuing my development. From here on out, it's strongly typed for me.

Of course all this changes at .NET 2.0 because we have generics to do this, but that's a story for another day (when I have a .NET 2.0 project!)

Re: Code Generation - In past projects we've done some code gen for ArcObjects via VB6 add-ins, and we'll be doing more on some upcoming projects (likey usign CodeSmith), and I'll post about that when the time comes. Should be fun!