In this post we’ll discuss the new Prototype Public Resource Management client. I uploaded the MSDN-style documentation to MSDN Code Gallery. The purpose of this post is to walk you through the direction I’m thinking about for a supported API. These ideas are a snapshot of my thinking today and will change in the future. I welcome feedback about both the high-level approach and specific granular details. There may be scenarios or features overlooked which should be incorporated into an eventual supported client.
Changes since the last version of the public prototype:
The basic architecture of the client has 3 layers: Default Client, WS-* clients, and WCF ClientBase. All three layers are publically accessible with the intention that your code can call the layer which is most appropriate. For most customers, the DefaultClient will be sufficient since it enables basic CRUD and Enumeration operations at a high level. The diagram below summarizes these three layers, with DefaultClient depending on the WS-* clients underneath it, and those clients depending on WCF ClientBase.
All of these classes are in the Microsoft.ResourceManagement.Client namespace. The DefaultClient is expected to be the client you use for 80% of scenarios. We intend it to be a low barrier to entry and sufficiently abstracted from the actual SOAP messages. Customers who need to modify the specific SOAP messages will need to use one of the WS-* clients. Customers who need to modify the WCF channel will have to use their own WCF ClientBase. Those three options should encompass 99% of all scenarios our customers want:
The object model is completely decoupled from the client into the Microsoft.ResourceManagement.ObjectModel namespace. There are two key points I would like to make.
First, there is a base class called RmResource which is a Dictionary. You can always use a key to index any attribute out of RmResource using the Dictionary interface. RmResource also exposes public properties for some well-known attributes like ObjectId and ObjectType so that developers can use Intellisense and pass those properties as arguments to methods.
We created derived classes RmPerson and RmGroup. These classes get the common public properties like ObjectId from the parent class, but they also expose additional attributes specific for their types. For example, RmPerson exposes FirstName and EmployeeId. RmGroup exposes ComputedMember and ExplicitMember. We intend to have a class for each object type in FIM and that each object type has all of the necessary promoted properties.
Since all of these objects are public, customers can create their own derived classes for custom object types in FIM. For example, Contoso may create a Contact object with an Email address. Contoso simply needs to create a new class that derives from RmResource and create a public property for Email. The class diagram below summarizes the relationships and intended inheritance:
Second, RmResource just stores data. To commit changes back to the web service, we’re musing with the idea of requiring transactions. The reason is our web service is designed to accept “differences” to objects rather than entire representations. We are considering calculating these differences with a transaction object rather than inside the RmResource object itself. At first glance it feels more clean to separate data and operations about the data. We’ll show how these transactions work in the upcoming examples, and we hope that you agree they are a natural way to program against the FIM web service.
I hope this was a useful introduction for our direction of the new prototype. Please contact me with feedback about this direction.