Microsoft “Oslo” MGraph – the next XML?

Microsoft’s upcoming “Oslo” modeling initiative is about tools and languages. MGraph is the piece within the language “M” that defines values, while MSchema is for schemas, functions and constraints and MGrammar is for textual DSLs. “Oslo” is still CTP and it will take some time until all concepts are available for production use.

By then, Microsoft plans to publish an open specification, such that everyone who wants to can implement the “M” language. Their ambition is to make it be as broad as XML is today.

Anyone can implement it. We want this approach wide spread on a variety of different platforms. We want it to be as broad as Xml is today.

Douglas Purdy, A Lap around “Oslo”

Today we have lots of XML on the wire. There’s also lots of JSON.

I want to see MGraph get there as well.

Jeff Pinkston alias Pinky:-), MGraph as a data rep

What is MGraph?

MGraph at it’s base is not a language. It is a simple contract for storing structured data in form of a labeled directed graph. This is a set of nodes where each node has an optional label and a set of successors, each of which may be a node or any other object.

The idea behind that is, that every structure can be exposed as a MGraph just by implementing the following interface, which is the core API behind MGraph.

I added some comments for easier understanding.

// Exposes whatever structure as an MGraph
public interface IGraphBuilder
{
  // Checks, if the object submitted is a value or a (custom) node.
  bool IsNode(object value);
  // Retrieves a comparer for the (custom) node objects.
  IEqualityComparer NodeComparer { get; }
  // Extracts the label from a (custom) node.
  object GetLabel(object node);
  // Extracts the successors from a (custom) node.
  IEnumerable GetSuccessors(object node);
  // Gets a (custom) node with a label.
  object DefineNode(object label);
  // Sets successors to a (custom) node.
  void DefineSuccessors(object protoNode, IEnumerable successors);
}

As you see, even the node is not specified by an interface or a base class. Both labels and successors are extracted by the visiting graph builder.

If you want, read more about the MGraph Api here.

MGraph as a language

What I do care more about is how MGraph’s textual notation looks like and how it compares to XML.

On MSDN you can find a language specification covering MSchema and MGrammar which both use parts of MGraph, but in a slightly different manner. Microsoft definitely plans to bring those pieces together

Today MGraph is used for values in MSchema extent initializers as well as for the AST (Abstract Syntax Tree) productions in MGrammar.

The basic syntax of MGraph very similar to JSON:

label { 
  otherLabel { "value" },
  "value",
},
"value"

As mentioned previously a successor can be either a node or a value. A value is just written directly, while a node is split into a label followed by its comma-separated successors within curly braces.

The same data as a XML-fragment would look like this:


  value
  value

value

One of the major differences is, that MGraph doesn’t distinguish attributes and elements. As XML is used today, anyone use attributes and elements according to their personal taste anyway.

Typed values

The next great difference is, that values are not just strings, but typed. Some of the intrinsic types are Text, Logical or Number.

mynode
{
  text { "some text" },
  number { 1234 }
  logical { true }
}

Find a list of the supported types in chapter 3.5 Intrinsic Types in the “Oslo” Modeling Language Specification.

Escaped Labels

While XML-elements and attributes are restricted to QName, a label in MGraph can be any object. They way how this is expressed in the textual syntax is not finished yet, but in MGrammar productions more complex strings are defined with an id-function.

id("some label xyz") 
{
  true, 
  id("another node") { "value" }
}

Ordered and unordered successors

In order to make a mapping to relational structures easier, successors are not sorted by default. In order to sort the successors, they have to be encapsulated in an integer-labeled node.

{
  0 { "value1" },
  1 { "value2" }
}

Which alternatively also can be expressed by brackets instead of braces. In the “M” jargon this is called a sequence.

[
  "value1",
  "value2"
]

Single successor nodes, or labeled values

A named value in MGraph is just a labeled node with a single value successor. The equals-sign is just some syntactic sugar for better read- and writability. In the “M” jargon this is called Entity, but this name is subject to change. Record structure might be a better name.

person
{
  name = "John Smith",
  age = 24
}

equals to

person
{
  name { "John Smith" },
  age { 24 }
}

Better than XML?

XML is great. Mostly because it can be read by almost every system, not because it has such a nice syntax. It was never meant for the purpose it is used for today either. It is a markup language for defining additional metadata onto text.

But what XML is broadly used for today, is configuration files, transport messages and even internal DSLs. For this kind of information, that has more structuring elements than data, XML is way to verbose.

Therefore I think MGraph with its tight syntax has the potential to become a great and broad alternative.

What do you think?

Comparing XML, JSON and MGraph

Continue reading

Retrieving the base definition for a PropertyInfo – .NET reflection mess

The Problem

Lets say you got a ClassA with SomeProperty and SomeMethod, plus a ClassB implementing ClassA and overriding both members.

public class ClassA
{
    public virtual bool SomeProperty
    //..

    public virtual bool SomeMethod()
    //..
}

public class ClassB : ClassA
{
    public override bool SomeProperty
    //...

    public override bool SomeMethod()
    //..
}

Now I want to reflect ClassB and find the base definition for each member.

For the virtual method, this is no problem:

typeof (ClassB).GetMethod("SomeMethod").GetBaseDefinition();

But PropertyInfo, does not offer this capability.

The Solution

I created an extension for PropertyInfo, that imitates the functionality of MethodInfo.GetBaseDefinition for properties.

Thanks, David for your suggestions (see first comment)!

public static class ReflectionExtensions
{
    /// <summary>
    /// When overridden in a derived class, returns the <see cref="propertyInfo"/> object for the 
    /// method on the direct or indirect base class in which the property represented 
    /// by this instance was first declared. 
    /// </summary>
    /// <returns>A <see cref="propertyInfo"/> object for the first implementation of this property.</returns>
    public static PropertyInfo GetBaseDefinition(this PropertyInfo propertyInfo)
    {
        var method = propertyInfo.GetAccessors(true)[0];
        if (method == null)
            return null;

        var baseMethod = method.GetBaseDefinition();

        if (baseMethod == method)
            return propertyInfo;

        var allProperties = BindingFlags.Instance | BindingFlags.Public 
            | BindingFlags.NonPublic | BindingFlags.Static;

        var arguments = propertyInfo.GetIndexParameters().Select(p => p.ParameterType).ToArray();

        return baseMethod.DeclaringType.GetProperty(propertyInfo.Name, allProperties, 
            null, propertyInfo.PropertyType, arguments, null);
    }
}

Shouldn’t be hard to create a GetBaseDefinition() for EventInfo based on this either.

.NET Reflection Library Mess

I removed this chapter, because it was based on wrong assumptions. The good news is, that the mess isn’t that big, neither 😉

Run R# tests without switching to the mouse

As I do test-driven development, I find it annoying to switch over to the Mouse every time I want to run my tests.

So I just hooked up a hotkey for running unit tests.

CTRL+ALT+T usually shows the Test Session pane – I’ve never used it, so I assigned it to:

ReSharper.UnitTest_ContextRun

Context_Run runs the test method your cursor is inside, or if you move out of the method it will run the whole test fixture.

CTRL+SHIFT+F6 (Switch to previous window pane) then brings the focus back to your code.

kick it on DotNetKicks.com