Check out my new blog at https://shibumiware.blogspot.com

Friday, May 09, 2008

Microsoft Project Fx (mpFx) - First Code

I have some code laid down for mpFx that demonstrates how the object model might work, including the use of the "Lazy Loading" pattern.  I have also built a small test harness, which we will discuss in this post.

Creating an Instance of ProjectServer

The test harness show in Figure 1 supports Windows and forms authentication.  Below is the code (error handling removed) that creates the ProjectServer instance.  The object model employs the "resource acquisition is resource utilization" paradigm.

if (formsAuthenticationRadioButton.Checked)
{
    _ProjectServer = new ProjectServer(projectServerUrlTextBox.Text,
                                       userNameTextBox.Text,
                                       passwordTextBox.Text);
}
else
{
    _ProjectServer = new ProjectServer(projectServerUrlTextBox.Text);
}
Figure 1 - Test Harness Login

image

Figure 2 shows the list of projects and resources retrieved from the server.

Figure 2 - Project and Resource List

I need to update this image... Sorry!

Loading the resource list, for example, is done like this:

SetStatusText("Loading resources...");

TreeNode resourcesNode = treeView.Nodes[0].Nodes["resourcesNode"];

foreach (Guid resourceGuid in _ProjectServer.Resources)
{
    TreeNode thisResource = new TreeNode();

    thisResource.Tag = resourceGuid;
    thisResource.Text = _ProjectServer.Resources[resourceGuid];
    thisResource.ImageKey = "user";
    thisResource.SelectedImageKey = "user";

    resourcesNode.Nodes.Add(thisResource);
}

projectsNode.ExpandAll();    

There are a couple of interesting things going on here.  First, underlying data structures are initialized until you access them through a property getter.  For example, the call to _ProjectServer.Resources in the foreach loop causes the enumerator to be initialized and returned, which in turn initializes the ResourcesWebService, calls ReadResources, initializes an internal dictionary that holds the resource Guid and name, and then yields the first result back to the foreach loop.

IEnumerator<Guid> IEnumerable<Guid>.GetEnumerator()
 {
     if (_resourceList == null)
     {
         LoadResourceList();
     }
 
     foreach (KeyValuePair<Guid, string> pair in _resourceList)
     {
         yield return pair.Key;
     }
 }
 
 public IEnumerator GetEnumerator()
 {
     return ((IEnumerable<Guid>)this).GetEnumerator();
 }

LoadResources() looks like this:

private void LoadResourceList()
{
    if (_resourceList == null)
    {
        _resourceList = new Dictionary<Guid, string>();
    }
    else
    {
        _resourceList.Clear();
    }
 
    using(ResourceDataSet resourceDataSet = 
            _Parent.ResourcesWebService.ReadResources(Filters.MinimumResourceInformation, false))
    {
        foreach (ResourceDataSet.ResourcesRow resource in resourceDataSet.Resources.Rows)
        {
            _resourceList.Add(resource.RES_UID, resource.RES_NAME);
        }
    }           
}

Note that a static property of the Filters class is accessed in the call to ReadResources().  The Filters class contains standard filters that can be used to ease development.  MinimumResourceInformation looks like this:

public static string MinimumResourceInformation
{
    get
    {
        Filter filter = new Filter();
 
        using (ResourceDataSet resourceDataSet = new ResourceDataSet())
        {
            filter.FilterTableName = resourceDataSet.Resources.TableName;
 
            filter.Fields.Add(new Filter.Field(resourceDataSet.Resources.RES_NAMEColumn.ColumnName));
            filter.Fields.Add(new Filter.Field(resourceDataSet.Resources.RES_UIDColumn.ColumnName));
 
            return filter.GetXml();
        }
    }
}

Okay, I am getting the evil eye so I will try to pick this up later.

No comments :

Disclaimer

Content on this site is provided "AS IS" with no warranties and confers no rights. Additionally, all content on this site is my own personal opinion and does not represent my employer's view in any way.