The Service Object Model Producer generates the communication layer between the server and a client side. It’s based on Windows Communication Foundation (WCF) and generates the needed services and contracts to expose your object model, as well as an enhanced proxy which allows us developers to create Smart-Clients without having to take care of all communication aspects.
This communication layer is absolutely standard WCF, so you can configure it as you wish using your desired addresses, bindings and configurations. Likewise, since the generated services and contracts are standard WCF services you don’t have to use the generated proxy, you could perfectly consume those web services using the Microsoft Visual Studio generated proxy.
However, the generated proxy is in fact a little more than a just a proxy. It’s in fact a remote version of the generated Business Object Model (BOM), and since it takes care of all communication aspects, it actually provides Smart-Client developers the same development experience as when developing a rich client: you’re manipulating Customers, Orders, Products, and not Channels, Endpoints and Factories, and that’s why we named it the Smart-Client Object Model (SCOM).
Using CodeFluent Entities, the Service Object Model Producer – with its generated services, contracts and Smart-Client Object Model – is the way to create Smart-Clients. Furthermore, the generated SCOM can also be used in Silverlight 2 and upper, so the same Smart-Client Object Model can be used for all your Smart-Clients whether they are standard .NET apps (Windows Forms, WPF, etc.) or Silverlight Apps.
Want to know more? Here’s a set of links that might be of interest to you:
Have you ever taken a look in your installation directory and wondered what’s all that stuff? Well here’s a quick description of all exes
CodeFluent.Build.exe (aka the builder)
That’s the most important, it’s the one that actually builds your model! It takes a model as a parameter, and generates the code by calling all the producers you declared in it.
More information here: CodeFluent Builder
CodeFluent.Import.exe (aka the importer)
This one is pretty neat: it allows you to create a CodeFluent Entities model starting from an existing database or model.
CodeFluent.Modeler.Portable.exe (aka the portable modeler)
That’s a standalone version of the Visual Studio Integrated Modeler. It’s basically for users without Visual Studio who which to get a graphical representation of a model.
More information here: CodeFluent Modeler
CodeFluent.Runtime.ServiceHost.exe (aka the service hoster)
This is a generic service that can be used to host any kind of services, including WCF ones. It takes care of all the plumbing, service registration, start, stop, multi threading, log, etc… It supports CodeFluent Generated services as well as other manually coded services. A developer has a minimum effort to do to host any piece of .NET code in a Windows Service fashion. It also supports a command line/console mode which is often handy in development phases. You can print your traces and exceptions directly on the console. It also embeds a special out-of-the-box WCF exception handler that is capable of displaying WCF server errors without using any other external tool like the Service Trace Viewer.
More information here: Service Hoster
CodeFluent.View.exe (aka the Meta Model Explorer)
Provides a user interface to load a model and explore the inferred model so you can see what CodeFluent Entities understood from your model before it generates anything. This tool gets very handy when you’re trying stuff, writing complicated methods or aspects, since you can validate that it behaves as expected without having to generate over all the time.
More information here: Meta Model Explorer
As explained in a previous post, that’s a licensing tool. First it allows you to activate the product but also to retrieve developer builds other than the official ones available in your account page, on the web site.
One of the new features of the Modeler is the Model Grid which provides developers a grid view of their model. This way you can get a complete transversal view of all concepts you defined in your model (all defined entities, methods, properties, rules, enums, etc.).
To open the Model Grid, select your model (or one of its namespaces) in the solution explorer and click “Show Model Grid” in its contextual menu:
The Model Grid is in fact a dockable Visual Studio pane, so you can dock it wherever you want, let it float, or tab it as a document, it’s all up to you . Once opened you’ll see all your entities and enumerations listed in the grid:
Using selectors on the left hand side of the grid, you’ll be able to view in the grid some more concepts. (Selectors are in fact XPath expressions on the inferred model, check-out The CodeFluent Entities API documentation article for more information on this.) For instance, clicking on the “Methods” selector, selects all methods on all entities that you defined (“/entity/method”). Leaving your mouse a second on a selector will display a tooltip indicating which selector it is, as well as showing it’s XPath query upon the inferred model.
Here’s what happens if I enable it on the SoftFluent.CarRental example model:
By default, a set of predefined selectors are available but you can remove or even add your own new extra ones by doing a right-click in the grid, and opening the “Selectors Chooser”.
The same is possible for the columns of the grid. By default, only the “Name” column is displayed but you can add extra-columns thanks to the “Columns Chooser”. By the way, the “Columns Chooser” is also a great way to view all available attributes on all CodeFluent concepts
Please note, that as of today (build 50518.593) the Model Grid is still being developed and is subject to change.
Since mid-March, the Modeler ships a new feature known as the Model and Database Explorer which, as the name suggests, lets you explore databases (or XMI and Enterprise Architects models) directly from Visual Studio. The tool provides built-in support for the following databases:
- Access 2007/2010,
- Access / Jet,
- OLE DB,
- SQL Server,
- SQL Azure,
- SQL Server CE.
It provides a centralized way to view any databases supported by CodeFluent Entities (either for import or generation purposes) so you don’t have to switch from tool to tool, and you’ll see precisely what CodeFluent Entities sees and understands from those databases (detected tables, keys, constraints, etc.)
For instance, once you generated and deployed your scripts on your online SQL Azure database, within Visual Studio you can explore the generated database, including its data. Talking about viewing data, unlike Microsoft’s SQL Azure Database Manager, Guids and Blobs can be viewed in the explorer
To use it, right-click on your CodeFluent Entities project in the Solution Explorer, and select Model and Database Explorer:
By default the default connection string of your project is available. If you want to explore a new data source, either add it to your project connection strings, or make a right click on left pane and click Connect:
Select your database engine type, and provide the connection string to it. You’ll then be able to navigate through your database.
Notice the Data property in the property grid pane? If you click on its “…” button, a new window will pop-up showing all contained data of the current table. This way it provides a unified and quick way for developers to view their data from Visual Studio and on multiple platforms.
CodeFluent users define their business logic in a platform independent model where each concept will be translated into an actual component by what we call producers and which are basically code generators.
Therefore the business logic is decoupled from technical aspects, even though it’s still possible to include platform specific stuff in your model if you need to.
However, the targeted platforms have their limitations such as Oracle supporting identifiers up to 30 characters in length. So what happens if I define a 40 character long entity?
Well the Oracle Producer will automatically take care of it: the corresponding table identifier will be trimmed-down to a unique 30 characters long identifier. The same logic applies to all identifiers (columns, stored procedures, views, etc.), so that you can model your application regardless of the underlying technology, while at the same time, if needed, you still can define platform specific stuff in your model like a PL-SQL stored procedure for instance.
This way your model is freed from such limitations, and if later on you want to change your persistence layer implementation from Oracle to SQL Server or vice versa, switch your producers and you’re good to go :)
CFQL actually provides built-in support for Many-To-Many relations, which often seems unnatural to developers. As a consequence, a common mistake is to write raw SQL to access a value contained in a Many-To-Many relation property, when in fact it can be done without any extra work.
For instance, in the following example a User can have several Roles, and one Role can be assigned to several Users. Nevertheless, if you want to load all users with a role name containing a specific token, instead of writing a raw SQL query, you could do it in a single line CFQL query, such as:
<Email typeName="Email" collectionKey="true"/>
<cf:method name="LoadByRoleToken" body="load(string token) where Roles.Name contains @token" />
<Name collectionKey="true" />
<Users typeName="UserCollection" />
As you can see in the example above, you can access entity properties using dots even on collection properties :)
A new version (R11) of the product documentation was released!
This new version includes:
- Producer namespaces documentation now lists typeNames as well,
- The Methods section,
- Enumerations article,
- Type System article,
- CodeFluent Query Language section
- A new technical article: SoftFluent.Advertising: a purely model-driven application
- An article on good design practices,
- A new Editing Data With Excel And Access section,
- A new Storing Data section,
- New articles documenting how to create CodeFluent Aspects (formerly known as CodeFluent Patterns),
- Documentation on the Documentation Producer,
- Generating Text Files (documentation on the Template engine, and built-in templates)
- As well as miscellaneous corrections.
Interested in some extra articles? Comment this post and tell us what you’d like to see in the next release!
CFQL is made to use entities directly, you don’t have to use their keys explicitly (even though you can). The key point in CFQL is to be decoupled from the database’s physical definition, so keep it as simple as possible using entities for maximum flexibility. Here’s an example illustrating this point. One could be tempted to write such a CFQL query:
<cf:method name="DeleteByRoleId" body="delete(int RoleId) where Role.Id=@RoleId " />
Of course, this method is valid, however writing so implies that the identifier of the Role entity is of the integer type, so if you change its type, or change its key into a composite key, you’ll have to write this method over. However, using entities directly instead of their keys solves this issue:
<cf:method name="DeleteByRole" body="delete(Role) where Role=@Role" />
Both CFQL queries will actually produce the same SQL statement, however the second version is way more flexible.
For this 100th post on the blog, we thought it could be a good idea to share a little bit of history about the product and where it found its roots.
Although we are now very clear about the positioning of the product and the key benefits of Model-Driven as we explained it on our company blog yesterday, it would be wrong to imagine we woke up one morning thinking we would create the next generation model-driven software factory.
So what were our observations and our goals when we started to design CodeFluent Entities?
1. Avoid redoing work as technology evolves
The first motivation came from our field experience on many development projects. We observed that we were repeating a lot of low value-added tasks. As technology evolution accelerates, the feeling of redoing always the same work a different way led us to find an approach to define functional elements in a sustainable way.
2. Easily deal with user change requests
Separating the functional elements from the technology-related implementation quickly gave us an obvious benefit in terms of change management. It is easy to continuously adjust design of entities, properties, relationships and rules once these elements are centralized within a single model. And one thing we know for sure, whatever the methodology or project, is that functional change will occur, as it is illusory to control it.
3. Connect layers with no effort
Another key element that quickly became obvious as a target was to be able to make sure all the generated pieces work together. This is “by design” in CodeFluent Entities approach but it took a lot of effort to get there and it also explains most of our design decisions. For example, the development of CFQL (CodeFluent Query Language), a simplified yet powerful language to describe methods dealing with data, was initiated to provide the minimal concepts to encompass the needs at both data and business tier.
4. Resolve once, benefit everywhere
The ultimate goal we targeted was to ensure the best coding patterns and solution could be deployed everywhere across the application. Producing the code automatically from a model made this goal realistic and we pushed the ability really far through the aspect dimension that allows anyone using the product to extend the standard features with his own best practices.
As a conclusion, “smart laziness” was our primary driver, and we just wanted to make the business software development process easier.
Of course, we had to theorize a bit to get there, but we did not start with the theory, as we are basically field people with real life project experiences.
This simple vision of key goals we were pursuing as developers map directly with the key benefits of our offering that decision-makers at our customers have observed, and that we have formalized in our software development white paper as our tenets.
Daniel Cohen-Zardi, CEO
By portable models I mean a model that someone else can retrieve from the source server and build right away without having to edit it.
To do so the idea is to avoid writing hard-coded paths or server names in the model in order to keep it as portable as possible. CodeFluent Entities supports environment variables as well as relative paths, so use them whenever needed to achieve this goal.
For instance, the following line will fail on 64-bit machines, or configurations where CodeFluent Entities was installed somewhere else:
<cf:pattern path="C:\Program Files\SoftFluent\CodeFluent\Current\Patterns\SoftFluent.Localization.xml" step="Methods" />
Using an environment variable instead, makes the path used specific to the current machine or user:
<cf:pattern path="%CF_PATTERNS_PATH%\SoftFluent.Localization.xml" step="Methods" />
Note: CF_PATTERNS_PATH is part of several well-known environment variables recognized by the product. Other available ones are CF_CURRENT_PATH, CF_TEMPLATES_PATH, CF_DEFAULT_PERSISTENCE_SERVER, CF_BUILD_NUMBER.
Likewise, avoid writing connection strings in your model, because if another developer doesn’t have access to the pointed server, he won’t be able to build the model without editing it. Instead, CodeFluent Entities uses the CF_DEFAULT_PERSISTENCE_SERVER environment variable as the default server to connect to. Therefore, instead of hard-coding server names, set this environment variable to the desired server, then you might not even have to set a connection string in your model.
This last point was actually covered in this previous post: Default Persistence Server.