Microsoft Code Generation Tools

Posted by Dave Bouwman | Posted in .NET, Devt Tools | Posted on 29-09-2006

3

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…

 

Mocking ArcObjects with NMock

Posted by Dave Bouwman | Posted in .NET, ArcGIS Devt, Team System | Posted on 18-09-2006

4

Things are going well with our ArcDAL project (Code Generation + Geodatabase = Goodness), and now that our base class library is pretty solid, I’m adding in unit tests. We want these tests to be run on every build, on any development system, so I want as much separation between the tests and any underlying required resources – for example – ArcSDE instances. Conveniently Scott Hanselman’s podcast from last week was all about using Mock objects in unit testing.

What is a Mock?
Basically, a mock object is a “fake” object that is created solely for the purpose of running a test. It’s generated on the fly using some mocking framework, and you basically tell it what to expect in terms of requests (properties / methods) and what to return. One place where this is really handy is when you want to avoid binding your tests to a specific instance of ArcSDE, or a specific file location for a personal geodatabase. It can also be used to avoid having to make calls out to other ArcObjects if you don’t actually need to.

I’ll go through a simple example to show what I mean…

Example:
Before I go any further, let me say that I’m using Visual Studio 2005, and the MSTest framework, but this will be pretty much the same in VS2003, and/or NUnit.

We’ll look at the tests for a Workspace Utility class…


This class just has 3 very simple shared methods which return information about an IWorkspace. The thing is that in order to test this with real instances IWorkspace, we’d need to actually connect to ArcSDE and a personal geodatabase. And this will make the tests brittle, as it’s unlikely that we’ll keep an instance up for a long time, and file paths will be different on different development machines.

Thus, we use Mock objects to “fake” the workspace. I’ve chosen to use the NMock2 framework for two basic reasons: a) free and b) works.

I’ve gone ahead and had Visual Studio create a set of tests for this class for me. This is a pretty handy feature of VS2005 – it looks at your classes and spits out a basic test harness to use as a starting point.

    ”’<summary>

    ”’A test for IsAccessWorkspace(ByVal ESRI.ArcGIS.Geodatabase.IWorkspace)

    ”’</summary>

    <TestMethod()> _

    Public Sub IsAccessWorkspaceTest()

        Dim workspace As IWorkspace = Nothing

        Dim expected As Boolean

        Dim actual As Boolean

        actual = ArcDAL.WorkspaceUtil.IsAccessWorkspace(workspace)

        Assert.AreEqual(expected, actual, “Did not return the expected value.”)

    End Sub

Now, if we were doing this without mocks, we’d need to actually connect to a personal geodatabase, and pass that into our WorkspaceUtil class. Like this…

    ”’<summary>

    ”’A test for IsAccessWorkspace(ByVal ESRI.ArcGIS.Geodatabase.IWorkspace)

    ”’</summary>

    <TestMethod()> _

    Public Sub IsAccessWorkspaceTest()

        Dim workspacefactory As IWorkspaceFactory = New AccessWorkspaceFactoryClass

        Dim connectionProperties As IPropertySet = New PropertySetClass

        connectionProperties.SetProperty(“DATABASE”, “C:\Test Data\ArcDAL\SampleData.mdb”)

        Dim workspace As IWorkspace = workspacefactory.Open(connectionProperties, 0)

        Dim expected As Boolean

        Dim actual As Boolean

        actual = ArcDAL.WorkspaceUtil.IsAccessWorkspace(workspace)

        Assert.AreEqual(expected, actual, “Did not return the expected value.”)

    End Sub

But, now we have a hardcoded path in the test. Now, we could get crafty, and read the file location from a configuration file, but that’s not the point of this post!

So – to add in Mock objects, add a reference to NMock2 and include/import the NMock2 namespace in your test class. To make things easier, I setup the mock workspace in the ClassStartup method which runs before the tests are executed.

    Private Shared _mockWorkspace As IWorkspace

    ‘Startup

    <ClassInitialize()> _

    Public Shared Sub MyClassInitialize(ByVal testContext As TestContext)

        Dim mocks As New NMock2.Mockery

        _mockWorkspace = CType(mocks.NewMock(GetType(IWorkspace)), IWorkspace)

    End Sub

So – this has created a member variable of type “IWorkspace” which is in reality a mock. At this point we just have a mock, but we tell the mock what to “expect” and how to respond in the tests themselves.

    ”’<summary>

    ”’A test for IsAccessWorkspace(ByVal ESRI.ArcGIS.Geodatabase.IWorkspace)

    ”’</summary>

    <TestMethod()> _

    Public Sub IsAccessWorkspaceTest_Mock()

        Expect.Once.On(_mockWorkspace).GetProperty(“Type”).Will(NMock2.Return.Value(esriWorkspaceType.esriLocalDatabaseWorkspace))             

        Dim workspace As IWorkspace = _mockWorkspace

        Dim expected As Boolean = True

        Dim actual As Boolean

        actual = ArcDAL.WorkspaceUtil.IsAccessWorkspace(workspace)

        Assert.AreEqual(expected, actual, “Did not return the expected value.”)

    End Sub

Hopefully the word-wrap cleans up that line, but it’s pretty simple, and follows a conversational type of logic.

Expect.Once.On(_mockWorkspace).GetProperty(“Type”).Will(NMock2.Return.Value(esriWorkspaceType.esriLocalDatabaseWorkspace))

Translates into:

Expect one call on _mockWorkspace to a Property called Type, Return a value of esriLocalDatabaseWorkspace

Pretty simple. The NMock framework takes care of actually “faking” out the IWorkspace, and then returns the specified value when the request it made. Here’s a shot of the tests in the results viewer. All green!

So, while this is a very simple example of how to use Mock objects with ArcObjects, I’ll be using this same methodology in other places as I add tests through the entire ArcDAL class library. I’m sure that there will be places where Mocks will not work (I suspect IFeature maybe a bit of a bear to mock), but it’s a start.

Finding Top Developers: What does it take?

Posted by Dave Bouwman | Posted in .NET, careers | Posted on 10-09-2006

3

While catching up on my blog reading, I ran across a series of articles by Joel Spolsky that talk about

These are very timely articles, as we are about to open
two “GIS Software Engineer” positions (I’ll post more details when the positions are formally
“open”), and it’s always been a challenge to locate top talent.

Joel argues (and I’d tend to agree) that “great developers”, the cream of the crop, just are not out in the marketplace. This is because their employers recognize this, and do what it takes to make sure they don’t even think about looking for another job.

On top of this, the market is pretty tight these days. A quick search for “software engineer” at
ESRI’s careers site lists 59 openings.
Just here in Fort Collins, Miner & Miner have at least one developer position
open, Riverside Technologies is looking for an ArcIMS developer,
and I’m sure that the various other staffing agencies which service the USDA are also
looking for people. Add to this the high-growth rate
of the geospatial industry
, and it’s clearly not an easy task to find
experienced geospatial developers.

Which leads to the question of how to get
top talent
?

In his “Field
Guide to Developers”
article, Joel lists a number of things he believes
developers care about at a job:

  • Private Offices
  • Good Chairs
  • Great Computers
  • Being treated well within the company
  • Not being micro-managed
  • Lack of useless office politics
  • Working on cool projects with cool technology

At the end of his
list, he states that compensation – as long as it’s on par with
industry standards – is less important than these other factors. Here’s the actual quote – which I think
is brilliant.

That doesnt mean you can underpay people, because they do care
about justice, and they will get infuriated if they find out that different
people are getting different salaries for the same work, or that everyone in
your shop is making 20% less than an otherwise identical shop down the road, and
suddenly money will be a big issue. You do have to pay competitively, but all
said, of all the things that programmers look at in deciding where to work, as
long as the salaries are basically fair, they will be surprisingly low on their
list of considerations, and offering high salaries is a surprisingly ineffective
tool in overcoming problems like the fact that programmers get 15″ monitors and
salespeople yell at them all the time and the job involves making nuclear
weapons out of baby seals

So assuming reasonable pay – what else
would draw you to an organization?

  • Opportunity to use different tools/technologies (i.e ArcGIS Server 9.2)?
  • A Herman Miller Aeron chair?
  • Working with people who are passionate about what they are doing?
  • Stock options?
  • Working on a large scale, multi-user system? 
  • Opporunity to hone / expand your skill set? 
  • Quad-screen, 2x dual-core system with 4GB or RAM?
  • A chance to make a difference?
  • Location?
  • Opportunities for career advancement?

Other ideas? What brought you to your current job? What keeps you there?

Temporary Post Used For Style Detection (92b246aa-a2df-4d6f-a8c3-93fc08f159b4)

Posted by Dave Bouwman | Posted in Uncategorized | Posted on 09-09-2006

0

This is a temporary post that was not deleted. Please delete this manually. (76b448af-c937-4ac8-b1cc-febca0f53189)

Development Philosophy

Posted by Dave Bouwman | Posted in .NET, Devt Tools, Fundamentals, Software | Posted on 01-09-2006

0

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.

.NET Databinding the Geodatabase

Posted by Dave Bouwman | Posted in .NET, ArcGIS Devt, Devt Tools | Posted on 01-09-2006

2

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.

Code Generation + Geodatabase = Goodness

Posted by Dave Bouwman | Posted in .NET, ArcGIS Devt, Software | Posted on 01-09-2006

2

Back in July I posted about an idea we had to generate a set of Geo-Objects from a Geodatabase. The idea was to effectively “hide” the ArcObjects details and allow us to work with the classes in our Geodatabase as though they were… well… classes. Real classes. We wanted to use code generation so we could skip a lot of tedious coding, and be more tolerant of changes in the model.

Anyhow, I’ve now got this working. It’s pretty slick so I thought I’d write up a quick post about it. I’ll be giving a talk about this at the September ArcDeveloper meeting in Fort Collins, and I’ll post the power point here and at ArcDeveloper.net

This is basically a set of screen caps that run through the process.

Step 1: Export geodatabase schema to Xml, using Xslt to simplify it. This is done via an ArcCatalog tool…

Step 2: Create a Class Libaray project in Visual Studio, and use CodeSmith to read the Xml file and generate the code into the project folder.

Generated files in Explorer…

Step 3: Include the files in the visual studio project, and build it. For grins, you can now create a class model diagram, which we can compare to the fields in our geodatabase.

So, that’s the code side of things. From here we can very easily work with the geodatabase classes without a whole mess of ArcObjects code muddying up our business tier.