DataContract types not visible inside FaultContract ?

Topics: Service Factory Modeling Edition Forum
Jun 16, 2008 at 7:29 PM
Is there a particular design reason that the generated code for the FaultContract project does not see DataContract types. When I add a DataContract as a memeber of a FaultContract, the FaultContract project does not get an automatic reference to the DataContract project.
Adding the Reference and changing the types to DataContracts.<type> instead of <type> fixes the problem.
Tried to fix the template to add the reference, but ran into multiple issues, the main roadblock was that using a member from CurrentElement.DataMembers caused an exception that stated that ArtifactLink is not implemented by the type.
Something to the effect of 
 foreach(DataMember member in CurrentElement.DataMembers)
 {  
    if( memberType != null )
    {    
        if (member is ModelElementReference)
        {
            ModelElementReference dcde = (ModelElementReference)member;
            Microsoft.Practices.Modeling.CodeGeneration.Artifacts.ArtifactLink alink = GetArtifactLink(dcde.ModelElement);
        }
    }
 }

Jun 17, 2008 at 11:40 PM

Hi jkatorbis, the following changes to the DataContract template should make this work. The template name is DataContract.tt and it's located in the DataContractDSL project-->TextTemplates-->WCF-->CS directory. Modify the method PopulateMemberVars to look as below (changes in bold). Then build the projects DataContractDSL, DataContractDSLPackage and Service Factory Guidance Package. The code changes are pretty similar to what you sent but basically note that to get the proper artifact link, you should use the DataContract element associated with the DataMember, instead of using the ModelElementReference itself.


private void PopulateMemberVars(DataMember member)

 

{

      string dataElementAttrInfo = "";

     

      if (member is PrimitiveDataType)

      {

            PrimitiveDataType pde = (PrimitiveDataType)member;

           

            if(pde.CollectionType == null)

            {

                  memberType = Utility.GetCSharpTypeOutput(pde.Type, pde.IsNullable);

            }

            else

            {

                  if(pde.IsNullable && Utility.CanBeNullable(pde.Type))

                  {

                        memberType = Utility.GetCSharpTypeDeclaration(pde.CollectionType, Utility.GetCSharpTypeOutput(pde.Type, pde.IsNullable));

                  }

                  else

                  {

                        memberType = Utility.GetCSharpTypeDeclaration(pde.CollectionType, pde.Type);

                  }

            }

      }

      else if (member is ModelElementReference)

      {          

            ModelElementReference dcde = (ModelElementReference)member;

            string type = dcde.Type;

           

            if (CurrentElement is FaultContract)

            {

                  Contract found = CurrentElement.DataContractModel.Contracts.Find(delegate(Contract contract)

                  {

                        return contract.Name == dcde.Type;

                  });

                  if (found != null && found is DataContract)

                  {

                        Microsoft.Practices.Modeling.CodeGeneration.Artifacts.ArtifactLink alink = GetArtifactLink(found);

                        AddProjectReference((Microsoft.Practices.Modeling.CodeGeneration.Artifacts.IArtifactLink)alink);

                        type = alink.Namespace + "." + dcde.Name;

                  }

            }          

            memberType = Utility.GetCSharpTypeDeclaration(dcde.CollectionType, type);

      }                                                    

 

    WCFDataElement dateElementInfo = GetObjectExtender<WCFDataElement>(member);

    if(dateElementInfo != null && member.IsDataMember)

    {

            dataElementAttrInfo = ", IsRequired = " + dateElementInfo.IsRequired.ToString().ToLowerInvariant() + ", Order = " + dateElementInfo.Order.ToString();

    }

 

      memberName = member.Name;

      memberPrivateName = Utility.ToCamelCase(memberName); 

      memberAttribute = member.IsDataMember ? "\r\n\t\t[WcfSerialization::DataMember(Name = \"" + memberName + "\"" + dataElementAttrInfo + ")]" : String.Empty;                                             

}


Thanks.



jkatorbis wrote:
Is there a particular design reason that the generated code for the FaultContract project does not see DataContract types. When I add a DataContract as a memeber of a FaultContract, the FaultContract project does not get an automatic reference to the DataContract project.
Adding the Reference and changing the types to DataContracts.<type> instead of <type> fixes the problem.
Tried to fix the template to add the reference, but ran into multiple issues, the main roadblock was that using a member from CurrentElement.DataMembers caused an exception that stated that ArtifactLink is not implemented by the type.
Something to the effect of 
 foreach(DataMember member in CurrentElement.DataMembers)
 {  
    if( memberType != null )
    {    
        if (member is ModelElementReference)
        {
            ModelElementReference dcde = (ModelElementReference)member;
            Microsoft.Practices.Modeling.CodeGeneration.Artifacts.ArtifactLink alink = GetArtifactLink(dcde.ModelElement);
        }
    }
 }




Jun 19, 2008 at 10:54 PM
It works! This is a good example of how to get an ArtifactLink from an arbitrary element of the model. Thanks.