dllcodefluent

Create/Use Codefluent CodeDomSubProducer


I'm attempting to create a CodeFluent SubProducer based on CodeFluent's document at: https://www.softfluent.com/documentation/CustomSubProducer_Topic.html

As the document describes, I've created a Visual Studio (2015) C# class library project named CodeDomSubProducer. Within this project I've added the three references for CodeFluent.Model.dll, CodeFluent.Model.Common.dll and CodeFluent.Producers.CodeDom.dll. I also added an interface, ICodeDomSubProducer, and a class, CodeDomSubProducer, with the code supplied in the document.

After compiling the program, I copied the CodeDomSubProducer.dll to %ProgramFiles(x86)%\SoftFluent\CodeFluent\Modeler.

I've altered my model's CFP file as described in the article.

When I attempt to build the model, the following error is presented: CF6003: Type 'CodeDomSubProducer.CodeDomLightProducer, CodeDomSubProducer' is not a CodeDomSubProducer.

Any suggestions on how I can resolve this error would be greatly appreciated.

Thanks!

  [1]: https://www.softfluent.com/documentation/CustomSubProducer_Topic.html

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using CodeFluent.Producers.CodeDom;
    using System.Collections;
    using System.CodeDom;

    namespace CodeDomSubProducer
    {
        interface ICodeDomSubProducer
        {
            // Methods
            void Initialize(CodeDomBaseProducer baseProducer, SubProducer subProducer, IDictionary context);
            void Produce(IDictionary context, CodeCompileUnit unit);
            void Terminate(IDictionary context);
        }
    }

    //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    using System;
    using System.Collections.Generic;
    using System.Text;
    using System.Collections;
    using System.Xml;
    using System.CodeDom;
    using CodeFluent.Model;
    using CodeFluent.Producers.CodeDom;
    //using CodeFluent.Runtime.Utilities;

    namespace CodeDomSubProducer
    {
        public class CodeDomLightProducer : ICodeDomSubProducer
        {protected static string namespaceUri = "http://www.softfluent.com/codefluent/producers.lightProducer/2005/1";
            public virtual void Initialize(CodeDomBaseProducer baseProducer, CodeFluent.Producers.CodeDom.SubProducer subProducer, IDictionary context)  
            {baseProducer.CodeDomProduction += new CodeDomProductionEventHandler(OnCodeDomProduction); }
            public virtual void Produce(IDictionary context, CodeCompileUnit unit) {}
            public virtual void Terminate(IDictionary context) {}
            private void OnCodeDomProduction(object sender, CodeDomProductionEventArgs e)
            {if (e.EventType == CodeDomProductionEventType.UnitsProducing)
                {if (e.Argument == null)
                        return;
                    foreach (CodeCompileUnit codeCompileUnit in (CodeCompileUnit[])e.Argument)
                    {foreach (CodeNamespace codeNamespace in codeCompileUnit.Namespaces)
                        {foreach (CodeTypeDeclaration codeTypeDeclaration in codeNamespace.Types)
                            {BaseType baseType = UserData.GetBaseType(codeTypeDeclaration);
                                XmlElement xmlElement = (baseType is Set) ? ((Set)baseType).ItemEntity.Element : baseType.Element;
                                List<string> methodsToHide = new List<string>();
                                foreach (XmlAttribute xmlAttribute in xmlElement.Attributes)
                                {if (xmlAttribute.NamespaceURI == namespaceUri)
                                    {if (xmlAttribute.LocalName == "exclude")
                                        {foreach (string method in xmlAttribute.Value.Split('|'))
                                                methodsToHide.Add(method);
                                        } } }
                                for (int i = 0; i < codeTypeDeclaration.Members.Count; i++)
                                {if (codeTypeDeclaration.Members[i] is CodeMemberMethod)
                                    {CodeMemberMethod method = codeTypeDeclaration.Members[i] as CodeMemberMethod;
                                        if (methodsToHide.Contains(method.Name))
                                        {if (((method.Attributes & MemberAttributes.Public) == 0) &&
                                                ((method.Attributes & MemberAttributes.Static) == 0))
                                            {codeTypeDeclaration.Members.Remove(method);
                                                i--;
        } } } } } } } } } }

    //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


  <cf:project defaultNamespace="TwoCollections" 
              xmlns:cf="http://www.softfluent.com/codefluent/2005/1" 
              xmlns:cfx="http://www.softfluent.com/codefluent/modeler/2008/1" 
              xmlns:cfps="http://www.softfluent.com/codefluent/producers.sqlserver/2005/1" 
              xmlns:cfom="http://www.softfluent.com/codefluent/producers.model/2005/1" 
              xmlns:cflp="http://www.softfluent.com/codefluent/producers.lightProducer/2005/1"
              defaultTargetFramework="4.6.1" 
              defaultConnectionString="Database=TwoCollections;Server=\\.\pipe\MSSQL$SQLEXPRESS\sql\query" 
              createDefaultMethodForms="true" 
              createDefaultApplication="false" 
              createDefaultHints="false">
  <cf:import path="Default.Surface.cfp" />
  <cf:producer name="SQL Server Producer" typeName="CodeFluent.Producers.SqlServer.SqlServerProducer, CodeFluent.Producers.SqlServer">
    <cf:configuration 
        connectionString="Database=TwoCollections;Server=\\.\pipe\MSSQL$SQLEXPRESS\sql\query" 
        produceViews="true" targetVersion="Sql2008" 
        targetDirectory="..\TwoCollectionsC.Persistence" 
        cfx:targetProjectLayout="UpdateItems, DontRemove" 
        cfx:targetProject="..\TwoCollectionsC.Persistence\TwoCollectionsC.Persistence.sqlproj" />
  </cf:producer>


  <cf:producer name="BOM Producer" typeName="CodeFluent.Producers.CodeDom.CodeDomProducer, CodeFluent.Producers.CodeDom, Version=1.0.0.0, Culture=neutral, PublicKeyToken=1bb6d7cccf1045ec">
    <cf:configuration 
        compileWithVisualStudio="true" 
        targetDirectory="..\TwoCollections" 
        cfx:targetProject="..\TwoCollections\TwoCollections.csproj" 
        codeDomProviderTypeName="CSharp" 
        cfx:targetProjectLayout="Update" >
    <!-- Custom Sub-Producer  -->
      <subProducer typeName="CodeDomSubProducer.CodeDomLightProducer, CodeDomSubProducer" />
    </cf:configuration>
  </cf:producer>


  <cf:entity name="SpaceX" cflp:exclude="Input|Save|Delete" namespace="TwoCollections" categoryPath="/TwoCollections">
    <cf:property name="GUIDx" key="true" />
    <cf:property name="DataX1" />
    <cf:property name="DataX2" />
    <cf:property name="ParentX" cascadeSave="After" cascadeDelete="Before" typeName="{0}.SpaceYCollection" relationPropertyName="ChildY" />
  </cf:entity>
  <cf:entity name="SpaceY" namespace="TwoCollections" categoryPath="/TwoCollections">
    <cf:property name="GUIDy" key="true" />
    <cf:property name="DataY1" />
    <cf:property name="DataY2" />
    <cf:property name="ChildY" typeName="{0}.SpaceX" relationPropertyName="ParentX" />
  </cf:entity>
</cf:project>

Solution

  • Great thanks to meziantou, based on his spotting the conditional statement error, and one more tweak, the OnCodeDomProduction function's condition should be <> (!=0) and OrElse (||):

    if (((method.Attributes & MemberAttributes.Public) != 0) ||
        ((method.Attributes & MemberAttributes.Static) != 0))
    

    This removes the three methods of insert, save, and delete.

    The resulting library, however, only complains about not having a save and a delete method.