TypeDescriptor Class
Defines the data type of a parameter for a method.
Inheritance Hierarchy
System.Object
Microsoft.Office.Server.ApplicationRegistry.Administration.MetadataObject
Microsoft.Office.Server.ApplicationRegistry.Administration.AccessControlledMetadataObject
Microsoft.Office.Server.ApplicationRegistry.Administration.TypeDescriptor
Namespace: Microsoft.Office.Server.ApplicationRegistry.Administration
Assembly: Microsoft.SharePoint.Portal (in Microsoft.SharePoint.Portal.dll)
Syntax
'Declaration
<SharePointPermissionAttribute(SecurityAction.InheritanceDemand, ObjectModel := True)> _
<SharePointPermissionAttribute(SecurityAction.Demand, ObjectModel := True)> _
Public Class TypeDescriptor _
Inherits AccessControlledMetadataObject
'Usage
Dim instance As TypeDescriptor
[SharePointPermissionAttribute(SecurityAction.InheritanceDemand, ObjectModel = true)]
[SharePointPermissionAttribute(SecurityAction.Demand, ObjectModel = true)]
public class TypeDescriptor : AccessControlledMetadataObject
Remarks
Every Parameter object has a TypeDescriptor object that defines the data type of the parameter. It is the most complex metadata object. It is a hierarchical object that recursively describes an abstract data structure built of primitives. In addition, each leaf node of the TypeDescriptor tree points to a set of possible default values specified by the MethodInstance object Therefore, given a MethodInstance and a parameter, the parameter's TypeDescriptor is a recipe to instantiate a default value for that parameter.
In addition, TypeDescriptors form the heart of the Business Data Catalog's ability to transform complex backend APIs into simple stereotypical operations like Find, FindSpecific, CheckAccess, ad so on. Once you define detailed type information via the TypeDescriptor metadata, you can tag TypeDescriptors as slots where Identifiers or Filter values can be plugged in by the Business Data Catalog. For example, a TypeDescriptor in a Parameter that is tagged to receive the Identifier for an Entity, results in a Method that can be used as a SpecificFinder.
Use the IsCollection property on a return TypeDescriptor object to indicate wherever there are collections within the return parameter. Consider a Web method that return collections of customers, each customer of which contains a collection of Addresses. In this example, the flag must be set twice—once at the root Customer[] level, and then again at the Customer[0].Address[] level. However, a collection TypeDescriptor object can have only a single child TypeDescriptor object under it that represents the structure in the collection.
Business Data Catalog clients such as the Business Data Web Parts do not handle complex structures. For example, consider the following structures:
class Customer { String Name; Address address; }
class Address { Street street; String city; String zip; }
class Street { int Block; String street; }
To work around this limitation, Business Data Catalog supports the concept of "complex formatting." Because clients support flat structures of primitives, the Business Data Catalog will "render" complex structures as formatted strings via two mechanisms: a simple .NET Framework String formatter, or a more complex Renderer that one can write using any .NET language. This is accomplished by setting two String properties with the names "FormatString" (e.g. "{0}, {1} \n {2}, {3}") or "RendererDefinition" (MyMethodName!MyTypeName, MyAssemblyName), respectively. The Method object in the RendererDefinition must correspond to a public static .NET method on a public .NET Type that takes a single argument, which is an array of Objects. In either case, what gets passed to the Format string or to the .NET Renderer is basically an array of all the primitive child values of the complex structure, as modeled by the Business Data Catalog TypeDescriptor definition for that structure.
Warning
Complex formatting is slow; use it only if absolutely necessary.
A controlling property called "ComplexFormatting" must appear on any structure that contains complex fields, to enable complex rendering.
Note
Be careful when tagging identifiers for complex formatting, because identifiers are used for both input and output to the back-end application (when getting the Addresses for a Customer, the Business Data Catalog looks for the Customer Key to give to the GetAddressesForCustomer method). If an identifier has been rendered as a formatted string, all type information is lost and it can no longer be used as input.
Schema
Child |
Type |
Occurs |
Default |
Limits / Accepted Values |
Description |
---|---|---|---|---|---|
TypeName |
Attribute (String) |
1..1 |
Min. length: 1 Max. length: 255 |
Name of the type in the line-of-business (LOB) system's type system that is described by this TypeDescriptor object. The ITypeReflector interface associated with this TypeDescriptor object's Parameter object is responsible for resolving this LOB system type into a .NET Type. In the case of both Web services and databases (Microsoft ADO.NET), the "LOB system type system" is .NET, so the value of TypeName is simply a .NET Type name. However, in the case of web services, the type name is followed by a ',' and the LobSystemName. |
|
IdentifierName |
Attribute (String) |
0..1 |
Name of the identifier represented by this TypeDescriptor object. If this TypeDecsriptor object describes an input parameter of a SpecificFinder mehtod, the parameter is populated with the identifier's value when you call FindSpecific. If this TypeDescriptor object describes an output parameter or a Finder or SpecificFinder method, the value of the parameter is included in the identifier values collection of returned entity instances when you call FindFiltered or FindSpecific. |
||
IdentifierEntityName |
Attribute (String) |
0..1 |
The entity containing this TypeDescriptor object |
Name of the entity that contains the identifier represented by this TypeDescriptor object. IdentifierEntityName is necessary when you model an association as a method on a source entity. In this case, the source entity returns instances of the destination entity, so you must set IdentifierEntityName to the name of the destination entity. |
|
AssociatedFilter |
Attribute (String) |
0..1 |
Max. TypeDescriptor objects per FilterDescriptor: 10 |
Name of the filter associated with this TypeDescriptor object. |
|
IsCollection |
Attribute (Boolean) |
0..1 |
false |
Specifies whether the TypeDescriptor object represents a collection. If true, the TypeDescriptor object must contain exactly one child TypeDescriptor object that describes an element in the collection. The return parameter of a Finder method must have a TypeDescriptor with IsCollection = true. |
|
DefaultValues |
Element |
0..1 |
Max. default values per TypeDescriptor object: 10 |
Container element for DefaultValue. |
|
TypeDescriptors |
Element |
0..1 |
Max. TypeDescriptor objects per TypeDescriptor: 300 |
Container element for TypeDescriptor. |
Properties
Following are the properties that the TypeDescriptor object accepts for both database and Web service systems.
Property |
Type |
Required |
Default Value |
Limits/Accepted Values |
Comments |
---|---|---|---|---|---|
DisplayByDefault |
System.Boolean |
No |
false |
true false |
If true, this field is displayed by default in the Business Data Web Parts and in the Business Data Picker. |
Examples
The following code example shows you how to create a method, complete with method instances, filter descriptors, default values, and type descriptors, for the ProductModel entity in the AdventureWorks database.
Prerequisites
Make sure a Shared Service Provider has already been created.
Create an LOBSystem instance and set connection parameters as shown in How to: Create an LobSystem Using the Administration Object Model.
Create the ProductModel entity as shown in How to: Create an Entity Using the Administration Object Model
Replace the constant value EnterYourSSPNameHere in the code with the name of your Shared Resource Provider.
Project References
Add the following Project References in your console application code project before running this sample:
Microsoft.SharePoint
Microsoft.SharePoint.Portal
Microsoft.Office.Server
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Office.Server.ApplicationRegistry.Administration;
using Microsoft.Office.Server.ApplicationRegistry.Infrastructure;
using WSSAdmin = Microsoft.SharePoint.Administration;
using OSSAdmin = Microsoft.Office.Server.Administration;
namespace Microsoft.SDK.SharePointServer.Samples
{
class GetStartedAndCreateSystem
{
const string yourSSPName ="EnterYourSSPNameHere";
static void Main(string[] args)
{
SetupBDC();
CreateFinderMethod();
Console.WriteLine("Press any key to exit...");
Console.Read();
}
static void SetupBDC()
{
SqlSessionProvider.Instance().SetSharedResourceProviderToUse(yourSSPName);
}
static void CreateFinderMethod()
{
LobSystemInstance mySysInstance = null;
LobSystemInstanceCollection sysInsCollection = ApplicationRegistry.Instance.GetLobSystemInstancesLikeName("AdventureWorksSampleFromCode");
foreach (LobSystemInstance sysInstance in sysInsCollection)
{
if (sysInstance.Name == "AdventureWorksSampleFromCode")
{
mySysInstance = sysInstance;
break;
}
}
EntityCollection entityColl = mySysInstance.LobSystem.Entities;
foreach (Entity entity in entityColl)
{
if (entity.Name == "ProductModel")
{
Method meth = entity.Methods.Create("GetProductModels", true, true);
meth.Properties.Add("RdbCommandText", "SELECT ProductModelID, Name, CatalogDescription FROM ProductModel WHERE Name LIKE @Name");
meth.Properties.Add("RdbCommandType", System.Data.CommandType.Text);
FilterDescriptor fd = meth.FilterDescriptors.Create("Name", true, "Microsoft.Office.Server.ApplicationRegistry.Runtime.WildcardFilter");
Parameter p1 = meth.Parameters.Create("@Name", true, Microsoft.Office.Server.ApplicationRegistry.MetadataModel.DirectionType.In, "Microsoft.Office.Server.ApplicationRegistry.Infrastructure.DotNetTypeReflector");
TypeDescriptor td1 = p1.CreateRootTypeDescriptor("Name", true, "System.String", null, fd, false);
Parameter p2 = meth.Parameters.Create("ProductModels", true, Microsoft.Office.Server.ApplicationRegistry.MetadataModel.DirectionType.Return, "Microsoft.Office.Server.ApplicationRegistry.Infrastructure.DotNetTypeReflector");
IList<Identifier> ids = new List<Identifier>(entity.Identifiers);
Identifier id = ids[0];
TypeDescriptor td2 = p2.CreateRootTypeDescriptor("ProductModelDataReader", true, "System.Data.IDataReader, System.Data, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089", null, null, true);
TypeDescriptor td21 = td2.ChildTypeDescriptors.Create("ProductModelDataRecord", true, "System.Data.IDataRecord, System.Data, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089", null, null, false);
TypeDescriptor td210 = td21.ChildTypeDescriptors.Create("ProductModelID", true, "System.Int32", id, null, false);
TypeDescriptor td211 = td21.ChildTypeDescriptors.Create("Name", true, "System.String", null, null, false);
TypeDescriptor td212 = td21.ChildTypeDescriptors.Create("CatalogDescription", true, "System.String", null, null, false);
MethodInstance methInst1 = meth.MethodInstances.Create("ProductModelFinder", true, td2, Microsoft.Office.Server.ApplicationRegistry.MetadataModel.MethodInstanceType.Finder);
MethodInstance methInst2 = meth.MethodInstances.Create("ProductModelSpecificFinder", true, td2, Microsoft.Office.Server.ApplicationRegistry.MetadataModel.MethodInstanceType.SpecificFinder);
IList<MethodInstance> methInstCollection = new List<MethodInstance>(entity.MethodInstances);
td1.SetDefaultValue(methInstCollection[0].Id, "%");
td1.SetDefaultValue(methInstCollection[1].Id, "%");
Console.WriteLine("Created the finder method successfully.");
break;
}
}
}
}
}
Thread Safety
Any public static (Shared in Visual Basic) members of this type are thread safe. Any instance members are not guaranteed to be thread safe.
See Also
Reference
Microsoft.Office.Server.ApplicationRegistry.Administration Namespace