Reduce ArcGIS Server Boilerplate Code By Implementing IDisposable

by James Richards April 19, 2009

When programming with ArcObjects and ArcGIS Server, code often follows a common pattern of connecting to ArcGIS Server, getting hold of an IServerContext, doing some work, and releasing the context. This leads to a lot of unnecessarily repeated setup and teardown code, usually taking a form similar to the following example:

IServerContext context = null;

try

{

    IGISServerConnection conn = new GISServerConnectionClass()

        as IGISServerConnection;

 

    // Connect as ASPNET or NETWORK SERVICE.

    // Get optional host setting from web.config,

    // or use localhost if not found.

    string host = ConfigurationManager.AppSettings["AGSHost"];

    if (String.IsNullOrEmpty(host))

    {

        host = "localhost";

    }

 

    // Make connection

    conn.Connect(host);

    IServerObjectManager som = conn.ServerObjectManager;

    context = som.CreateServerContext("MyServer", "MapServer");

   

    // Do some stuff with the server context

}

finally

{

    if (context != null)

    {

        context.ReleaseContext();

    }

}

In this example, there is a lot of boilerplate happening just to get to the server context and do something interesting. Seeing this kind of code repeated throughout an ArcGIS Server project made me a little queasy as it violates the DRY Principle, so that got me thinking about how to eliminate it. [more]

I decided to create a wrapper class that handles making the connection and implements IServerContext and IDisposable. Inspiration for this idea comes from the .NET SqlConnection class, which also implements IDisposable and can therefore be instantiated inside of a using block to automatically close the connection and release any resources when the using block goes out of scope. (See this David Hayden post for a basic discussion of why this is a good thing.) Proper implementation of IDisposable is known as the Dispose Pattern and is documented both here and in Cwalina and Adams excellent Framework Design Guidelines.

With this new class, we can reduce the boilerplate code block to the following:

using (ArcGisServerContext context = new ArcGisServerContext("MyServer",

    ArcGisServiceType.MapServer))

{

    // Do some stuff with the server context

}

Notice also the use of an Enum to indicate the server type, thus eliminating one of the error prone hard coded strings as well. (In a real application, I would also retrieve the value “MyServer” from a config or resource file.) The Enum is defined like so:

public enum ArcGisServiceType

{

    MapServer,

    GeocodeServer,

    GlobeServer,

    GPServer,

    GeoDataServer,

    GeometryServer,

    ImageServer,

}

and the ArcGISServerContext class is implemented as follows:

using System;

using System.Configuration;

using ESRI.ArcGIS.Server;

public class ArcGisServerContext : IServerContext, IDisposable

{

    #region Fields

    private IServerContext serverContext;

    #endregion

 

    #region Constructors()

    // Here you can add overloaded constructors to take additional

    // arguments such as login credentials - Or you could alter the

    // constructor to use an ArcGIS Server Identity from web.config.

 

    // This example just connects as the current user, which will be

    // ASPNET or NETWORK SERVICE if running under IIS on Wind XP or 2003.

    public ArcGisServerContext(string serviceName,

        ArcGisServiceType serviceType)

    {

        IGISServerConnection conn = new GISServerConnectionClass()

            as IGISServerConnection;

 

        // Get optional host setting from web.config,

        // or use localhost if not found.

        string host = ConfigurationManager.AppSettings["AGSHost"];

        if (String.IsNullOrEmpty(host))

        {

            host = "localhost";

        }

 

        // Make connection and cache IServerContext

        conn.Connect(host);

        IServerObjectManager som = conn.ServerObjectManager;

        serverContext = som.CreateServerContext(serviceName,

            serviceType.ToString());

    }

    #endregion

 

    #region IServerContext Implementation

    // These methods just pass through to the cached server context

 

    public object CreateObject(string clsid)

    {

        return serverContext.CreateObject(clsid);

    }

 

    public object GetObject(string name)

    {

        return serverContext.GetObject(name);

    }

 

    public object LoadObject(string str)

    {

        return serverContext.LoadObject(str);

    }

 

    public void ReleaseContext()

    {

        serverContext.ReleaseContext();

    }

 

    public void Remove(string name)

    {

        serverContext.Remove(name);

    }

 

    public void RemoveAll()

    {

        serverContext.RemoveAll();

    }

 

    public string SaveObject(object obj)

    {

        return serverContext.SaveObject(obj);

    }

 

    public IServerObject ServerObject

    {

        get { return serverContext.ServerObject; }

    }

 

    public void SetObject(string name, object obj)

    {

        serverContext.SetObject(name, obj);

    }

    #endregion

 

    #region IDisposable Implementation

    // Implementation of the Dispose Pattern

 

    public void Dispose()

    {

        Dispose(true);

        GC.SuppressFinalize(this);

    }

 

    protected virtual void Dispose(bool disposing)

    {

        // Release the server context

        if (disposing)

        {

            if (serverContext != null)

            {

                serverContext.ReleaseContext();

            }

        }

    }

    #endregion

}

 

It’s really pretty simple, and it sure is nice not to have to copy / paste or keep re-typing the same boilerplate code over and over.

Hope this helps!

Tags: , , ,

.NET | ArcGIS Server | Planet GS

How To Use URL Rewriting for Extensionless WCF Svc Services with Helicon Tech ISAPI Rewrite

by James Richards February 02, 2009

Recently I was working on a WCF Service and wanted to serve it up with extensionless URLs. I downloaded and installed ISAPI Rewrite (Lite version) but struggled to come up with the correct regex expression to get it working.

I found many good blog postings and clues from Scott Gu, Scott Hanselman, and Jeff Atwood, and a thread on Stack Overflow, but none of these answered this specific question. As Scott Hanselman noted, URL rewriting can seem like "freaking voodoo".

So I moseyed on over to the Helicon Tech support forum and [more] asked the question. Anton (who I assume is one of the good folks at Helicon Tech) swiftly and correctly answered the question with the following example:

RewriteBase /
RewriteRule ^MyProject/MyService/products(.*)?$ MyProject/MyService.svc/products$1 [NC,L]

You can follow the complete thread here.

I hope this helps!

Tags: , , , , ,

.NET | ASP.NET | How To | REST | WCF

Powered by BlogEngine.NET 1.6.0.0
Theme by Mads Kristensen | Modified by Mooglegiant
Creative Commons License This work is licensed under a Creative Commons Attribution 3.0 United States License.

Welcome

James Richards

Hi, I'm James Richards the CTO and co-founder of Artisan Global LLC. We make location-aware mobile apps with maps. I'm the author of QuakeFeed and I helped launch Zaarly at LASW Feb 2011. I also enjoy surfing, snowboarding, golfing, yoga, and music. I love my family: Linda, Sequoya and our cats Remy and Twiggy. Thanks for stopping by, I hope you find something helpful here.

Subscribe by RSS   Follow me on Twitter   Connect on Facebook   View my profile on LinkedIn


Amazon Associates

Some of my posts may contain Amazon Associates links. I only include these links when it makes sense within the context of the article. If you are in the market for one of these items, please consider clicking on an affiliate link to make your purchase. You still get the same great deal from Amazon and it will help me pay for hosting and bandwidth. Thanks!