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