Cross-Model References

Retired Content

The Web Service Software Factory is now maintained by the community and can be found on the Service Factory site.

This content is outdated and is no longer being maintained. It is provided as a courtesy for individuals who are still using these technologies.
This page may contain URLs that were valid when originally published, but now link to sites or pages that no longer exist.

Retired: November 2011

The DSL SDK does not support cross-model reference out of the box. The Service Factory implements the following cross-model references as shown in Figure 1 in Building Services Using the Service Factory: Modeling Edition topic:

There are two references from the Service Contract model to the Data Contract model:

  • The Type property of the DataContractMessagePart is a reference to the DataContract model element.
  • The Type property of the **DataContractFault****is also a reference to the DataContract model element.

In the Host Designer model, the ServiceImplementation property of the ServiceReference model element is a reference to the Service model element in the Service Contract model.

The cross-model references are created and resolved by the classes in the DIS package. A reference is set by an editor and stored by a type converter, which are associated with a model element property via custom attributes. Below is a fragment of the DSL-generated code for the Type property of the **DataContractMessagePart****model element (you can find the code in the DomainClasses.cs file in GeneratedCode folder of the ServiceContractDsl project). The first three attributes have the following functions, respectively:

  • Associates the property editor called ExportedClassEditor with the property.
  • Associates the type convertor called ExportedInstanceConvertor with the property.
  • Defines the model and the type of the referenced model element; in this case, it is the DataContractBase in the Data Contract model.
[System.ComponentModel.Editor("Microsoft.Practices.Modeling.Dsl.Service.Editors.ExportedClassEditor, Microsoft.Practices.Modeling.Dsl.Service, Version=3.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35",typeof(System.Drawing.Design.UITypeEditor))]
[System.ComponentModel.TypeConverter(typeof(Microsoft.Practices.Modeling.Dsl.Service.ExportedInstanceConverter))]
[Microsoft.Practices.Modeling.Dsl.Service.TargetClass(@"Microsoft.Practices.ServiceFactory.DataContracts\DataContractBase")]
…
public global::System.String Type
{
[global::System.Diagnostics.DebuggerStepThrough]
get
{
return typePropertyStorage;
}
[global::System.Diagnostics.DebuggerStepThrough]
set
{
TypePropertyHandler.Instance.SetValue(this, value);
}
} 

The cross-model reference is a string with a specific structure referred to as a moniker. An example of a moniker is shown below. In this example, Microsoft.Practices.ServiceFactory.DataContracts\DataContractBase\Customer is the reference to the model element Customer inheriting from DataContractBase, and AccountService\CoreDataContract is the path to the model file in the model project.

mel://Microsoft.Practices.ServiceFactory.DataContracts\DataContractBase\Customer@AccountsService\CoreDataContracts

References are resolved by the DIS service implementing the IDslIntegrationService interface. An example of how a reference is resolved is shown in the following code fragment. The example method comes from the CrossModelReferenceValidator.cs validator class, which is in the Microsoft.Practices.ServiceFactory.Validation project in the Libraries solution folder.

protected virtual ModelElement ResolveReference(ModelElement currentElement, string reference)
{
Debug.Assert(currentElement != null);
if (currentElement == null)
{
throw new ArgumentNullException("currentElement");
}

IDslIntegrationService dslIntegrationService = (IDslIntegrationService)((IServiceProvider)currentElement.Store).GetService(typeof(IDslIntegrationService));
if (dslIntegrationService == null)
{
throw new InvalidOperationException(Resources.ModelReferenceValidator_NoDis);
}

return DomainModelHelper.ResolveModelReference(dslIntegrationService, reference, true);
}