Skip to content

Project Physical Layout

Simon Mourier edited this page Feb 19, 2020 · 1 revision

A CodeModeler project is stored on a disk using part files (.sfcm files). These part files are Xml files that contain human-readable Xml elements. By default, using Visual Studio, a project has only one part, but it’s possible, and sometimes desirable, to store concepts on different parts.

For example, you can user per-namespace parts (one part will contain all entities and enumerations defined in a namespace). One reason to split the project into multiple part is also to enable a better team development, because a part is the minimum storage unit, including in Source-controlled scenarios.

Multi-Parts Project

You can create a new Part using the Parts folder node context menu “Add Part” item. You must give the part a unique name which will be used as the part’s physical file name.

Let’s take this small model for example:

Multi-Parts Project - Picture 110

There are two entities (“Product”, “Customer”), each in a different namespace (“Commerce”, “Commerce.Sales”). We can create a part to store entities in the “Commerce.Sales” namespace in their own part:

Multi-Parts Project - Picture 111

Now the project looks like this:

Multi-Parts Project - Picture 112

We can see the two parts (note the default part has a small overlay icon in its upper right corner). Here is the Xml content of the first part that currently stores all the model:

<cm:project defaultNamespace="Commerce" xmlns:cm="http://www.softfluent.com/cm/2018/1" xmlns:cmm="http://www.softfluent.com/cm/m/2018/1">
  <cm:import path="Default.Surface.sfcm" />
  <cm:import path="Commerce.Sales.sfcm" overwrite="false" />
  <cm:entity name="Product" namespace="Commerce">
    <cm:property name="Id" key="true" />
    <cm:property name="Reference" />
  </cm:entity>
  <cm:entity name="Customer" namespace="Commerce.Sales">
    <cm:property name="Id" key="true" />
    <cm:property name="Name" />
  </cm:entity>
</cm:project>

And here is the content of the second part that stores no concept:

<cm:project defaultNamespace="Commerce" xmlns:cm="http://www.softfluent.com/cm/2018/1" />

If we select the “Customer” entity and use the Visual Studio Property Grid, we can change its part using the “Part” attribute:

Multi-Parts Project - Picture 113

If we choose “Commerce.Sales.sfcm”, the entity storage will be moved to the new part. Now the first (and default) part will contain this:

<cm:project defaultNamespace="Commerce" xmlns:cm="http://www.softfluent.com/cm/2018/1" xmlns:cmm="http://www.softfluent.com/cm/m/2018/1">
  <cm:import path="Default.Surface.sfcm" />
  <cm:import path="Commerce.Sales.sfcm" overwrite="false" />
  <cm:entity name="Product" namespace="Commerce">
    <cm:property name="Id" key="true" />
    <cm:property name="Reference" />
  </cm:entity>
</cm:project>

And the second (and new) one will contain this:

<cm:project defaultNamespace="Commerce" xmlns:cm="http://www.softfluent.com/cm/2018/1">
  <cm:entity name="Customer" namespace="Commerce.Sales">
    <cm:property name="Id" key="true" />
    <cm:property name="Name" />
  </cm:entity>
</cm:project>

Namespace Default Part

It’s possible to define a default part for a given namespace. In the design surface, you can select a namespace (clicking on its group shape) and in the Visual Studio Property Grid use the “Default Part” attribute:

Namespace Default Part - Picture 114

Now all concepts that will be added to this “Commerce.Sales” namespace will be stored in the “Commerce.Sales.sfcm” part / file.

Moving Parts

You can change entities and enumerations storage parts easily using the “Namespace Types Part” dialog box. To show this dialog box, you must select a namespace in a design surface, right click to open the surface context menu and choose the “Namespace Type Parts” menu item:

Moving Parts - Picture 115

In this dialog box you can choose a target storage part and select which of the types currently stored in the selected namespace you want to move over to this target storage part.

Xml Synchronization

CodeModeler parts use Xml. If you open a part directly from Visual Studio (for example if you double-click on an .sfcm node) you will see the part content.

For example, with a model like this, with a BOM producer and a SQL producer:

Xml Synchronization - Picture 324

The part will contain something like this:

<cm:project defaultNamespace="Commerce" xmlns:cm="http://www.softfluent.com/cm/2018/1" xmlns:cmm="http://www.softfluent.com/cm/m/2018/1" xmlns:cmo="http://www.softfluent.com/cm/model/2018/1" xmlns:cmsql="http://www.softfluent.com/cm/sqlserver/2018/1" xmlns:cmc="http://www.softfluent.com/cm/cache/2018/1" xmlns:cmt="http://www.softfluent.com/cm/template/2018/1" defaultSchema="{3}" defaultConnectionString="Data Source=KILROY;Integrated Security=True">
  <cm:import path="Default.Surface.sfcm" />
  <cm:producer name="Business Object Model (BOM)" typeName="CodeModeler.Producers.CodeDomProducer, CodeModeler.Producers">
    <cm:configuration compileWithVisualStudio="true" compile="false" codeDomProviderTypeName="CSharp" targetDirectory="..\Commerce" cmm:targetProject="..\Commerce\Commerce.csproj" cmm:targetProjectLayout="Update">
      <subProducer typeName="CodeModeler.Producers.CacheProducer, CodeModeler.Producers, Version=1.3.0.0, Culture=neutral, PublicKeyToken=6aca39712f080bb8" />
    </cm:configuration>
  </cm:producer>
  <cm:producer name="SQL Server" typeName="CodeModeler.Producers.SqlServer.SqlServerProducer, CodeModeler.Producers.SqlServer">
    <cm:configuration produceViews="true" targetDirectory="..\Commerce.Database" cmm:targetProject="..\Commerce.Database\Commerce.Database.sqlproj" cmm:targetProjectLayout="Update, DontRemove" connectionString="Server=KILLROY;Database=Commerce;Integrated Security=true;Application Name=Commerce" />
  </cm:producer>
  <cm:entity name="Customer" namespace="Commerce">
    <cm:property name="Id" key="true" />
    <cm:property name="Name" />
    <cm:property name="Orders" cascadeDelete="Before" typeName="{0}.OrderCollection" relationPropertyName="Customer" />
  </cm:entity>
  <cm:entity name="Order" namespace="Commerce">
    <cm:property name="ID" key="true" />
    <cm:property name="Customer" typeName="{0}.Customer" relationPropertyName="Orders" />
  </cm:entity>
</cm:project>

As you can see the Xml is very human readable and editable, and its synchronized both ways:

  • If you change the model from a design surface, the Xml will change. If the part is open in Visual Studio, its content will change automatically.

  • If you change the Xml from a part and Save the part (using Visual Studio), the model, and consequently the design surface will change.

The behavior is governed by the “Xml Edition” settings in Visual Studio’s Tools / Options / SoftFluent CodeModeler:

Xml Synchronization - Picture 328

Note: Although this feature can be useful in some situation, it’s not recommended to modify Xml manually directly from the part as it can lead to undefined results.

If you want to modify the Xml manually, we recommend you close the project from Visual Studio first.

Clone this wiki locally