Share via


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

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

TypeDescriptor Members

Microsoft.Office.Server.ApplicationRegistry.Administration Namespace