Live fx Helper Class
Everyone seems to have their own Live fx helper class. I use one myself to cleanup the sample code that I build to demonstrate functionality or to reproduce reported problems. In the past in the forums I’ve just put a little caveat into discussion to ignore that section of the code because it is indeed irrelevant to the point at hand. Generally it is just about boilerplate creation or discovery of mesh objects and feeds.
I want to publish this for two reasons
- To make all my code samples able to compile
- To expose a little more about how I work with the Live Framework
- So I can just link to this post instead of saying "Please ignore the man behind the curtain."
Also, you will notice I like to use extension methods for most of my helpers. This is sometimes a point of contention between developers kind of like the "Where do the brackets go?" debate. Some like extension methods, some think it confuses the consumer of the code. I see both points, but in the end you can use them either way – as extension methods or as static methods – so I’m going to leave that option in.
using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.LiveFX.Client;
using Microsoft.LiveFX.ResourceModel;
public static class LiveFXHelper
{
#region MeshHelpers
/// <summary>
/// Finds a MeshObject in a Mesh and optionally creates it if not found
/// </summary>
/// <param name="mesh">the Mesh to search</param>
/// <param name="title">the title of the Mesh Object to find</param>
/// <param name="createIfNotFound">if true, then the object will be created if not found</param>
/// <returns>the Mesh Object found or null if not found or created </returns>
public static MeshObject FindMeshObject(this Mesh mesh, string title, bool createIfNotFound)
{
var query1 = from coreObject in mesh.CreateQuery<MeshObject>()
where coreObject.Resource.Title == title
select coreObject;
MeshObject meshObject = query1.FirstOrDefault<MeshObject>();
if (meshObject == null && createIfNotFound)
{
meshObject = new MeshObject(title);
mesh.MeshObjects.Add(ref meshObject);
}
return meshObject;
}
/// <summary>
/// Finds a MeshObject in a Mesh
/// </summary>
/// <param name="mesh">the Mesh to search</param>
/// <param name="title">the title of the Mesh Object to find</param>
/// <returns>the Mesh Object found or null if not found</returns>
public static MeshObject FindMeshObject(this Mesh mesh, string title)
{
return FindMeshObject(mesh, title, false);
}
#endregion
#region MeshObjectHelpers
/// <summary>
/// Finds a DataFeed in a MeshObject and optionally creates it if not found
/// </summary>
/// <param name="mesh">the MeshObject to search</param>
/// <param name="title">the title of the DataFeed to find</param>
/// <param name="createIfNotFound">if true, then the object will be created if not found</param>
/// <returns>the DataFeed found or null if not found or created </returns>
public static DataFeed FindDataFeed(this MeshObject parent, string title, bool createIfNotFound)
{
var query1 = from coreObject in parent.CreateQuery<DataFeed>()
where coreObject.Resource.Title == title
select coreObject;
DataFeed dataFeed = query1.FirstOrDefault<DataFeed>();
if (dataFeed == null && createIfNotFound)
{
dataFeed = new DataFeed(title);
parent.DataFeeds.Add(ref dataFeed);
}
return dataFeed;
}
/// <summary>
/// Finds a DataFeed in a MeshObject
/// </summary>
/// <param name="mesh">the Mesh Object to search</param>
/// <param name="title">the title of the DataFeed to find</param>
/// <returns>the DataFeed found or null if not found</returns>
public static DataFeed FindDataFeed(this MeshObject parent, string title)
{
return FindDataFeed(parent, title, false);
}
/// <summary>
/// Determines if any invitations are still pending
/// </summary>
/// <param name="meshObject">The MeshObject whose invitations are being checked</param>
/// <returns>true if any invitations are still pending</returns>
public static bool AreInvitationsPending(this MeshObject meshObject)
{
var members = (from member in meshObject.CreateQuery<Member>()
where member.Resource.InvitationAccepted == false
select member).ToList();
return (members.Count() > 0);
}
/// <summary>
/// Converts a list of MeshObjects to into a list of
/// the corresponding MeshObjectResources. This is
/// especially helpful when binding to UI elements
/// </summary>
/// <param name="collection"></param>
/// <returns>A list of MeshObjectResources that were attached to the MeshObjects</returns>
public static List<MeshObjectResource> GetResourceList(List<MeshObject> entries)
{
List<MeshObjectResource> newList = new List<MeshObjectResource>();
foreach (MeshObject item in entries)
{
newList.Add(item.Resource);
}
return newList;
}
#endregion
#region DataFeed_Helpers
/// <summary>
/// Finds a DataEntry in a DataFeed and optionally creates it if not found
/// </summary>
/// <param name="mesh">the DataFeed to search</param>
/// <param name="title">the title of the DataEntry to find</param>
/// <param name="createIfNotFound">if true, then the object will be created if not found</param>
/// <returns>the DataEntry found or null if not found or created </returns>
public static DataEntry FindDataEntry(this DataFeed parent, string title, bool createIfNotFound)
{
var query1 = from coreObject in parent.CreateQuery<DataEntry>()
where coreObject.Resource.Title == title
select coreObject;
DataEntry dataEntry = query1.FirstOrDefault<DataEntry>();
if (dataEntry == null && createIfNotFound)
{
dataEntry = new DataEntry(title);
parent.DataEntries.Add(ref dataEntry);
}
return dataEntry;
}
/// <summary>
/// Finds a DataEntry in a DataFeed
/// </summary>
/// <param name="mesh">the DataFeed to search</param>
/// <param name="title">the title of the DataEntry to find</param>
/// <returns>the DataEntry found or null if not found</returns>
public static DataEntry FindDataEntry(this DataFeed parent, string title)
{
return FindDataEntry(parent, title, false);
}
/// <summary>
/// Converts a list of DataFeeds to into a list of
/// the corresponding DataFeedResources. This is
/// especially helpful when binding to UI elements
/// </summary>
/// <param name="collection"></param>
/// <returns>A list of DataFeedResources that were attached to the DataFeeds</returns>
public static List<DataFeedResource> GetResourceList(List<DataFeed> entries)
{
List<DataFeedResource> newList = new List<DataFeedResource>();
foreach (DataFeed item in entries)
{
newList.Add(item.Resource);
}
return newList;
}
#endregion
#region DataEntry_Helpers
/// <summary>
/// Converts a list of DataEntrys to into a list of
/// the corresponding DataEntryResources. This is
/// especially helpful when binding to UI elements
/// </summary>
/// <param name="collection"></param>
/// <returns>A list of DataEntryResources that were attached to the DataEntrys</returns>
public static List<DataEntryResource> GetResourceList(List<DataEntry> entries)
{
List<DataEntryResource> newList = new List<DataEntryResource>();
foreach (DataEntry item in entries)
{
newList.Add(item.Resource);
}
return newList;
}
#endregion
}
Comments
- Anonymous
March 09, 2009
How Do I Ensure My Mesh Object Is Available Everywhere I Need It? Let’s say you have a scenario in which - Anonymous
March 21, 2009
Ben,Correct me if I'm wrong (very possible - C# aint my strongpoint) but I can't use these methods in a MEWA. Here's why.The following:Application.Current.GetMeshApplicationService()returns a MeshApplicationService object whereas your methods here (e.g. FindDataFeed() ) assume that a MeshObject object is passed.I know its not too much hassle to take your code here and roll my own that takes a MeshApplicationService instead but I just wanted to check I wasn't missing something. Is there a way to exctract a MeshObject from a MeshApplicationService and hence use your helper class?ThanksJamie - Anonymous
March 22, 2009
Hi Ben,Ignore the above. I've added to what you've said here with a couple of extra methods of my own:Live fx Helper Class – extra methods(http://blogs.conchango.com/jamiethomson/archive/2009/03/22/live-fx-helper-class-extra-methods-live-framework.aspx)-Jamie - Anonymous
March 23, 2009
No there isnt a way to pull the right MeshObject out of the MeshApplicationService. I purposely dont have any MEWA specific stuff in here because I do most of my samples/testing as a console app for efficiency. I haven't ported this to MEWA yet and until we find a better way, it may be best to add the methods you created and just wrap them in an #ifdef flag so they will compile outside of a MEWA project. - Anonymous
March 23, 2009
In my helper library post Jamie Thompson rightly points out that the MeshObject helper doesn’t help that - Anonymous
March 23, 2009
#ifdef....I have no idea what that is :)I have some reading to do!!By the way, I ran your class through Resharper and it pointed out a couple of things - mainly parameter names in the summary section. Let me know if you want the resharpened version.-Jamie - Anonymous
March 23, 2009
That should be #if instead of #ifdef (ifdef is C++)http://msdn.microsoft.com/en-us/library/4y6tbswk.aspxAnyway, I was thinking of just wrapping the whole section in an "#if SILVERLIGHT" which would just cause regular .NET to skip it. But a quick compile reveals a serious issue - all the synchronous methods are gone in the new CTP. Doh! So for now this library is good for .NET but needs some retooling for Silverlight - Anonymous
March 30, 2009
A looping construct is one that is often requested in the Live Framework forum discussions regarding