ComplexObject Class

[WCF RIA Services Version 1 Service Pack 2 is compatible with either .NET framework 4 or .NET Framework 4.5, and with either Silverlight 4 or Silverlight 5.]

Base class for all complex objects.

Inheritance Hierarchy

System.Object
  System.ServiceModel.DomainServices.Client.ComplexObject

Namespace:  System.ServiceModel.DomainServices.Client
Assembly:  System.ServiceModel.DomainServices.Client (in System.ServiceModel.DomainServices.Client.dll)

Syntax

'Declaration
<DataContractAttribute> _
Public MustInherit Class ComplexObject _
    Implements INotifyPropertyChanged, IEditableObject, INotifyDataErrorInfo
'Usage
Dim instance As ComplexObject
[DataContractAttribute]
public abstract class ComplexObject : INotifyPropertyChanged, 
    IEditableObject, INotifyDataErrorInfo
[DataContractAttribute]
public ref class ComplexObject abstract : INotifyPropertyChanged, 
    IEditableObject, INotifyDataErrorInfo
[<AbstractClassAttribute>]
[<DataContractAttribute>]
type ComplexObject =  
    class
        interface INotifyPropertyChanged
        interface IEditableObject
        interface INotifyDataErrorInfo
    end
public abstract class ComplexObject implements INotifyPropertyChanged, IEditableObject, INotifyDataErrorInfo

The ComplexObject type exposes the following members.

Constructors

  Name Description
Protected method ComplexObject Created an instance of the ComplexObject.

Top

Properties

  Name Description
Public property HasValidationErrors Gets a value indicating whether this entity has any validation errors.
Protected property IsDeserializing Gets a value indicating whether this instance is currently being deserialized.
Public property ValidationErrors Gets the collection of validation errors for this instance.

Top

Methods

  Name Description
Protected method BeginEdit Begin editing this complex object instance.
Protected method CancelEdit Cancels any edits made to this instance since the last call to BeginEdit().
Protected method EndEdit Commits the edits made to this instance since the last call to BeginEdit().
Public method Equals (Inherited from Object.)
Protected method Finalize (Inherited from Object.)
Public method GetHashCode (Inherited from Object.)
Public method GetType (Inherited from Object.)
Protected method MemberwiseClone (Inherited from Object.)
Public method OnDeserialized Method called after a complex object has been deserialized.
Public method OnDeserializing Method called when a complex object is being deserialized.
Protected method OnPropertyChanged Called when the property of a complex object has changed.
Protected method RaiseDataMemberChanged Called from a property setter to notify the framework that a data member of a complex object has changed.
Protected method RaiseDataMemberChanging Called from a property setter to notify the framework that a data member of a complex object is about to be changed.
Protected method RaisePropertyChanged Called from a property setter to notify the framework that a complex object property has changed.
Public method ToString (Inherited from Object.)
Protected method ValidateProperty(ValidationContext, Object) Validates whether the specified property value is valid for a specified ValidationContext.
Protected method ValidateProperty(String, Object) Validate whether the specified value is valid for the specified property of the current complex object.

Top

Explicit Interface Implementations

  Name Description
Explicit interface implemetationPrivate method IEditableObject.BeginEdit Begin editing this instance of this complex object.
Explicit interface implemetationPrivate method IEditableObject.CancelEdit Cancels the edits made to this complex object instance since the last call to IEditableObject.BeginEdit().
Explicit interface implemetationPrivate method IEditableObject.EndEdit Commits the edits made to this complex object instance since the last call to IEditableObject.BeginEdit().
Explicit interface implemetationPrivate event INotifyDataErrorInfoErrorsChanged Explicitly implement the ErrorsChanged() event.
Explicit interface implemetationPrivate method INotifyDataErrorInfoGetErrors Retrieves the errors for the specified property, or the type-level errors if propertyName is nulla null reference (Nothing in Visual Basic) or empty.
Explicit interface implemetationPrivate property INotifyDataErrorInfoHasErrors Gets a value indicating whether or not the entity presently has errors.
Explicit interface implemetationPrivate event INotifyPropertyChanged.PropertyChanged Event raised whenever a ComplexObject property has changed.

Top

Remarks

A complex object type in WCF RIA Services is a structural custom user type that can be used like base type. The framework provides a lot of entity-like functionality such rich client code generation for complex types and much of the framework behavior for complex types is the same or very similar to that of entities. But a ComplexObject differs from an Entity in important ways. In particular, complex types do not have identities. This means that they do not have members marked with the KeyAttribute and so clients cannot do identity caching for them as it does for entities. Complex types cannot be shared or referenced from multiple parent instances and they do not support inheritance.

Assume you have an entity type Customer with a member of type Address:

public class Address
{
    public string AddressLine1 { get;set }
    public string City { get;set }
    public string Region { get;set }
    public string PostalCode { get;set }
    public string Country { get;set }
}

public class Customer
{
    [Key]
    public string CustomerID { get;set; }
    public string CompanyName { get;set }
    public string ContactName { get;set }

    public Address HomeAddress { get;set; }
}

These types will result in corresponding generated client types:

public class Address : ComplexObject
{
    public string AddressLine1 { . . . }
    public string City { . . . }
    public string Region { . . . }
    public string PostalCode { . . . }
    public string Country { . . . }
}

public class Customer : Entity
{
    [Key]
    public string CustomerID { . . . }
    public string CompanyName { . . . }
    public string ContactName { . . . }

    public Address HomeAddress { . . . }
}

Notice that Address derives from ComplexObject.

Code Generation

The client proxies generated for complex types are very similar to those generated for entities. This includes partial extensibility methods, validation metadata, etc. Code-generated complex types derive from the ComplexObject base class. The generated property setter logic for complex types members and members of complex types follows the same property patterns used for entities.

Metadata

As with entities, you can apply additional metadata to your complex types on the server via buddy classes, and that metadata will flow through the system. Similarly, in cases where you’re using a Data Access layer (DAL) that supports complex types, DAL metadata will also be applied (e.g. inferring the StringLengthAttribute for members based on your Entity Framework model). Complex types participate in the metadata pipeline the same way entities do.

Validation

Property setter validation is performed for complex type members in the same way that it is for entity members. In addition, validation errors for nested complex type members propagate up the containment hierarchy. Deep submit time validation is performed on both tiers for entity complex type members. In all cases, a nested validation error will be reported as an error on each parent up the hierarchy. For example, if the Customer.ContactInfo.HomeAddress.PostalCode member is invalid, that validation error will surface in the validation errors of the Customer, ContactInfo and HomeAddress instances. The member name(s) in the ValidationResult will be pathed appropriately at each level.

Change Tracking

Singleton entity complex type members (e.g. Customer.Address) fully participate in change tracking and the rest of the Accept/RejectChanges pipeline. As nested complex type members are changed, those changes are reported up the containment hierarchically causing the parent entity to become dirty. If changes are rejected on the entity, all nested complex type changes are reverted. Conceptually, nested complex type members are treated by the system the same way top level non- complex type entity properties are.

Complex types in collection members (e.g. Customer.PhoneNumbers) are not tracked deeply. They will be deeply validated at submit time, but validation errors are not raised on the entity as members are set on complex type instances in the collection, and the parent entity isn’t tracking whether instances in the collection have been modified, added or removed. To modify the contents of a complex type collection member, a new collection instance must be assigned to the member.

Edit Sessions

Entity complex type members fully participate in entity edit sessions initiated via the IEditableObject interface. If a BeginEdit() is performed on an entity, the state snapshot for the entity includes all nested complex type state recursively. Similarly if CancelEdit()/EndEdit() are performed, the changes are applied recursively. ComplexObject itself implements IEditableObject, so you get full edit session support for complex types not hosted by entities.

Serialization

Complex type members are always serialized deeply based on DataContract/DataMember annotations. This contrasts with entity associations, whose serialization is governed by the application of IncludeAttribute.

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

System.ServiceModel.DomainServices.Client Namespace