Create/UseCodefluent CodeDomSubProducer

Create/Use Codefluent CodeDomSubProducer

我正在尝试根据位于以下位置的 CodeFluent 文档创建 CodeFluent SubProducer:https://www.softfluent.com/documentation/CustomSubProducer_Topic.html

如文档所述,我创建了一个名为 CodeDomSubProducer 的 Visual Studio (2015) C# class 库项目。在这个项目中,我添加了 CodeFluent.Model.dllCodeFluent.Model.Common.dll[= 的三个引用45=]。我还添加了一个接口 ICodeDomSubProducer 和一个 class、CodeDomSubProducer,代码在文档中提供。

编译程序后,我将 CodeDomSubProducer.dll 复制到 %ProgramFiles(x86)%\SoftFluent\CodeFluent\Modeler。

我已经按照文章中的描述更改了模型的 CFP 文件。

当我尝试构建模型时,出现以下错误: CF6003:类型 'CodeDomSubProducer.CodeDomLightProducer, CodeDomSubProducer' 不是 CodeDomSubProducer

如有任何关于如何解决此错误的建议,我们将不胜感激。

谢谢!

  [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>

CodeDomSubProducer 必须实现 CodeFluent.Producers.CodeDom.dllCodeFluent.Producers.CodeDom.ICodeDomSubProducer 接口。在您的代码中,您重新声明接口。因此,CodeDomLightProducer 没有实现预期的接口,而是另一个具有相同方法和相同名称的接口。

要使其正常工作,您必须从生产者程序集中删除以下代码:

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

非常感谢 meziantou,根据他发现的条件语句错误,再进行一次调整,OnCodeDomProduction 函数的条件应该是 <> (!=0) 和 OrElse ( ||):

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

这里去掉了insertsavedelete三个方法。

然而,生成的库只抱怨没有 savedelete 方法。