1

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>
Greg Delaney
  • 81
  • 11
  • Are you sure the class implements `CodeFluent.Producers.CodeDom.ICodeDomSubProducer`? Can you post the code (producer + model)? Also, be sure to compile the producer with the right version of the .NET Framework: .NET3.5 if you use `CodeFluent.Build.exe` and .NET4 if you use `CodeFluent.Build4.exe`. – meziantou May 12 '17 at 08:42
  • I've added the code requested. With the exception the CF model's entities, I copied the code, without modification, from https://www.softfluent.com/documentation/CustomSubProducer_Topic.html I'm using VS 2015 to create/build the library and the modeler in VS 2015 to build the BOM. – Greg Delaney May 12 '17 at 10:46
  • You must not add the interface `ICodeDomSubProducer` in your code. The interface already exists in `CodeFluent.Producers.CodeDom.dll`. – meziantou May 12 '17 at 11:43

2 Answers2

1

A CodeDomSubProducer must implement the CodeFluent.Producers.CodeDom.ICodeDomSubProducer interface from CodeFluent.Producers.CodeDom.dll. In your code, you redeclare the interface. So, the CodeDomLightProducer doesn't implement the expected interface, but another one that has the same methods and the same name.

To make it work you must remove the following code from your producer assembly:

namespace CodeDomSubProducer
{
    interface ICodeDomSubProducer
    {
        // Methods
        void Initialize(CodeDomBaseProducer baseProducer, SubProducer subProducer, IDictionary context);
        void Produce(IDictionary context, CodeCompileUnit unit);
        void Terminate(IDictionary context);
    }
}
meziantou
  • 20,589
  • 7
  • 64
  • 83
  • Thanks meziantou! My first go around with this produced some errors, so I added the interface. Now that I've removed the interface, the model builds but the _insert, save, and delete_ are not excluded from the generated class. – Greg Delaney May 12 '17 at 12:59
  • If the aspect removes the `public static` methods, I think the condition isn't good: `if (((method.Attributes & MemberAttributes.Public) == 0) && ((method.Attributes & MemberAttributes.Static) == 0))`. It should be `!=`. – meziantou May 12 '17 at 17:37
  • Thanks for spotting the erroneous conditional statements. To remove both _save_ methods along with the _insert_ and _delete_ methods, the AndAlso (&&) operator also needed changing to OrElse (||). – Greg Delaney May 12 '17 at 21:43
0

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.

Greg Delaney
  • 81
  • 11