Development Tip: Feeder Manager 2.0 and Autoupdaters

January 26, 2015 — Corey Blakeborough

Feeder Manager 2.0 offers significantly better performance compared to its predecessor.  Primarily, because it stores information in memory.  

One of the biggest changes that this brings to an existing system is that this data is not explicitly associated with the table in the database for a given feature.

This association is made for you when running ArcMap, but does not exist explicitly when viewing the database separately, either using ArcCatalog, or viewing fields using ArcObjects. The latter can have a large impact on utilities looking to implement Feeder Manager 2.0 on a system that is already heavily customized.

That’s all right, as most good feature improvements require at least some change, but it’s important to understand all of the ways in which Feeder Manager 2.0 affects code.

The first implication, which is more explicitly known, is how to access Feeder Manager 2.0 fields. This information is covered in-depth within the ArcFM™ Desktop Developer Guide. The information provided there gives us a good method to retrieve general Feeder Manager 2.0 data. Take the example of retrieving the energized phases of a feature (“feat”):

IConnectionProperties connectionProps = new ConnectionProperties(((IDataset)feat.Class).Workspace); 
FeatureKey featKey = new FeatureKey(feat.Class.ObjectClassID, feat.OID); 
FeederInfoProvider provider = new FeederInfoProvider(connectionProps); 
IFeederInfo<FeatureKey> feeder2Info = provider.GetFeederInfo(featKey); 
Phases phases = feeder2Info.EnergizedPhases;

This method is effective in retrieving the correct Feeder Manager 2.0 data at the time. Note the emphasis!

The lesser-known caveat to retrieving Feeder Manager 2.0 lies in the way that the in-memory system works during updates. ArcFM™ autoupdaters fire as the feature in question is being changed. At this point, normal fields will already have been updated and the feature is about to be stored. But this isn’t when Feeder Manager 2.0 kicks into action.

Due to its architecture, Feeder Manager 2.0 actually waits until the entire edit operation is finishing before it updates its own data.

This is efficient and helps maximize performance and minimize version edits, but it also effectively means that retrieving Feeder Manager 2.0 data directly during the context of an autoupdater can be unreliable. You won’t be able to be sure if you’re getting the old value or the new one.

Don’t worry, though, as there is a solution!

By the time the edit operation is complete, the data will be reliable. As such, the correct approach is to use the autoupdater execution to track which features have been changed, pass these to a new singleton class, and use that class to listen to the Esri OnStopEditOperation method and process all relevant features at that time. You’ll still be using the same API as the one above.

Before you dive too deep into this method, the best news is that this approach will only be needed up through ArcFM™ version 10.2.1a. That’s because Schneider Electric is working on letting ArcFM™ perform most of this legwork behind the scenes at 10.2.1b, providing us with an easy-to-use event that we will be able to subscribe to.

If you’re working at 10.2.1a or earlier with Feeder Manager 2.0, though, the singleton class approach is the way to go. It requires some bare-bones code in order to subscribe to edit events.

The crucial step is to provide a method which will add a feature to a list that we will process later, and in that method, use the feature information (such as its workspace) to ensure that we’re subscribed to the OnStopEditOperation event. That event is where our logic will be performed. Additionally, subscribe to the OnStopEditing event, and use this event to unsubscribe after everything is finished.

A big thanks goes out to Schneider Electric for the insight and assisting with sample code to handle this scenario. Here is a snippet for your new singleton class that gets you most of the way:

private List<IFeature> _editedFeatures;
private IWorkspaceEditEvents_Event _editEvents;
private IWorkspaceEdit _workspaceEdit;
private FeederInfoProvider _feederInfoProvider;

public void LogEditedFeature(IFeature feederFeature)
{
    IWorkspace workspace = ((IDataset)feederFeature.Class).Workspace;
    Connect(workspace);
    _editedFeatures.Add(feederFeature);
}

#region Workspace edit events

private void OnStopEditOperation()
{
    foreach (IFeature feat in _editedFeatures)
    {
        ////retrieve FM2 info here, perform logic
    }
}

private void OnStopEditing(bool saveEdits)
{
    Unsubscribe();
}

#endregion

#region Subscribe / Unsubscribe

private IConnectionProperties _connection;

private void Connect(IWorkspace workspace)
{
    var connection = new ConnectionProperties(workspace);
    if (connection.Equals(_connection) == false)
    {
        Unsubscribe();
        SubscribeEditEvents(workspace);
        _connection = connection;
        _feederInfoProvider = new FeederInfoProvider(connection);
    }
}

private void SubscribeEditEvents(IWorkspace workspace)
{
    _workspaceEdit = (IWorkspaceEdit) workspace;
    _editEvents = (IWorkspaceEditEvents_Event) workspace;
    _editEvents.OnStopEditOperation += OnStopEditOperation;
    _editEvents.OnStopEditing += OnStopEditing;
}

private void Unsubscribe()
{
    _workspaceEdit = null;

    if (_editEvents != null)
    {
        _editEvents.OnStopEditOperation -= OnStopEditOperation;
        _editEvents.OnStopEditing -= OnStopEditing;
    }

    _connection = null;
    _feederInfoProvider = null;
}

#endregion

You don’t have to stop there, though! If you’re good with generic actions or events, you can expand this to make your singleton generic, too, so that all the logic stays in the AU but isn’t actually executed until the singleton chooses to fire it.

Using this method will allow your autoupdaters to stay consistent and grab reliable data. And don’t forget that 10.2.1b will make this Feeder Manager 2.0 code change even easier!

We Wrote the Book

The Indispensible Guide to ArcGIS Online

Download It for Free

Corey Blakeborough

Corey Blakeborough is a Team Lead, Senior Consultant at the Utility & Telecommunications GIS consulting company SSP Innovations in Centennial, Colorado. Corey has over five years of experience with SSP, providing a variety of GIS and work management solutions.

5 comments

    • SSP Innovations says:

      Hey Dane,

      The DLLs used in that first snippet are Miner.Geodatabase.dll and Miner.NetworkModel.dll.

      And if it helps, here are the usings:

      using Miner.Geodatabase;
      using Miner.Geodatabase.FeederManager;
      using Miner.Geodatabase.Network;
      using Miner.NetworkModel.Electric;

      Hope that helps!

      • Thanks, Corey but I don’t have those dll’s in my Assemblies under my Miner & Miner directory. I was afraid of that. We have 10.2 ArcFM but for some reason I still have the 10.1 Assemblies. Is there any way to get those from Schneider’s website.

        Thanks,
        Dane

        • SSP Innovations says:

          Dane, try ensuring that the SDK is installed. The assemblies you’re looking for should be in the GAC or in the \DotNet\Assemblies\ folder structure within the ArcFM Solution install directory. Note that all 10.2.X installations still use 10.1 as the assembly version – so it’s not necessarily incorrect for you to be seeing 10.1.

  • Dane Hopkins says:

    I just figured out why I don’t have the Miner.NetworkModel.Electric dll. It’s because we have ArcFM 10.2.1 not 10.2.1a!

What do you think?

Leave a comment, and share your thoughts

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes:

<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>