We recently announced, the CodeFluent Importer could now create a CodeFluent Entities model from a Enterprise Architect Model (http://codefluent.wordpress.com/2009/11/20/codefluent-and-enterprise-architect-the-first-stone-towards-importing-uml-model/). Well, in the same continuity, we’re announcing the release of a new beta feature of the CodeFluent Entities Importer: XMI 2.1 support. XMI is a standard, XML based, file format supported by several UML designers on the market such as the followings:
- Enterprise Architect (Sparx Systems),
- Magic Draw (No Magic Inc.),
- UModel (Altova),
- and many more!
For instance, here’s a model edited with Magic Draw UML 16.6:
By saving your model in XMI, and running the CodeFluent Entities Importer, you’ll get a CodeFluent Entities model. As an example, here’s the imported version of the previous model (viewed in CodeFluent Entities’ upcoming graphic editor):
Now that you have a CodeFluent Entities model, you’ll now be able to generate 100% functional components by defining your desired producers. If ever you want to know more about this new importer feature, feel free to contact us!
CodeFluent Entities R&D Team
Since business applications are commonly used by multitudes of end users, concurrency management is a common issue in business application development.
Concurrency is a well-known issue and you’ll find nice articles (such as this one) explaining what concurrency is, as well as common patterns to address it.
To sum-up, there are three common ways to address concurrency management when developing your application:
- No concurrency protection
Probably, the easiest to implement.
No concurrency protection implies several users can edit the same data, and the “last one wins” rule is applied.
In the optimistic concurrency model, users are always allowed to read the data, and perhaps even to update it. When the user attempts to save the data, however, the system checks to see if the data has been updated by anyone else since the user first retrieved it. If it has been changed, the update fails.
This concurrency model places locks on data. If one user has a record open and any other users attempt to read that data in a context that allows editing, the system denies the request.
CodeFluent Entities supports the optimistic concurrency protection model, and this concurrency protection is activated for all entities by default. However, having a concurrency protection doesn’t always make sense, may it be for business reasons or technical ones. In such cases, it’s then possible to disable concurrency at the project level:
<cf:project xmlns:cf="http://www.softfluent.com/codefluent/2005/1" defaultNamespace="Sample" defaultConcurrencyMode="None"> (...) </cf:project>
Or for a specific entity:
<Customer concurrencyMode="None"> (...) </Customer>
How it works
Entities with a concurrencyMode set to Optimistic (default) have an extra property named RowVersion that gets generated.
On each write operation, the RowVersion column in the persistence layer gets updated. Thanks to this property, CodeFluent can tell when a user tries to persist an obsolete version of an entity. This is done by comparing the persisted RowVersion to the one sent by the user: if ever they’re different, a CodeFluentConcurrencyException is raised.
Handling the CodeFluentConcurrencyException
When bumping into a CodeFluentConcurrencyException, the first question one should ask himself is: is it relevant to have concurrency protection on this business entity?
Having a concurrency protection doesn’t always make sense, may it be for business or technical reasons. For instance, a scenario where concurrency protection could be useless, would be in a case where children entities are automatically updated when a concurrency protected parent entity is updated: if updating the parent succeeded, updating children will.
Let’s get back to our exception and let’s say we do want concurrency protection on the entity that triggered the exception.
CodeFluent generates automatically a method named Reload which is made to help you handle those concurrency exceptions.
The Reload method takes as a parameter an enumeration named CodeFluentReloadOption which can be a combination of the following values:
Note: The Default value is actually set to Everything.
Thanks to this method, you’ll be able to handle your concurrency exception by calling the reload method with the right option. For instance, would you want to bypass the concurrency protection, you could reload just the RowVersion so that you can overwrite the current record.
On the other hand you could also reload you’re whole entity by calling this method and ask the user to start-over with his modifications.
CodeFluent Entities R&D team.
First of all happy new year to our readers
Yes, using CodeFluent Entities, you can store existing .NET types instances to the persistence layer (whatever that is: SQL Server, Oracle database, etc.). There are actually many ways to do it.
Ok, let’s suppose we want to store, say, graphical shapes in the database. We define this very simple model, defining coordinates, width and height of the shape bounding rectangle:
<Shape> <Id /> <BoundsX typeName="int" /> <BoundsY typeName="int" /> <BoundsW typeName="int" /> <BoundsH typeName="int" /> </Shape>
Here, .NET connoisseurs should object that this is heresy! There is an existing .NET type “Rectangle”, in the System.Drawing namespace, from the standard System.Drawing assembly, that already defines something similar. Can we use it? Yes, we can!
Out first shoot at this is:
<Shape> <Id /> <Bounds typeName="System.Drawing.Rectangle" /> </Shape>
That works fine because CodeFluent Entities tries to serialize everything it does not “know”. Known types are (using C# aliases when it exists): int, uint, long, ulong, short, ushort, byte, sbyte, byte, bool, float, double, decimal, string, char, System.Guid, System.DateTime, System.TimeSpan, explicit CodeFluent blob types (declared using “file”, “video”, “image”, “audio”), all enum (System.Enum) types.
For all other “unknown” types, CodeFluent Entities uses serialization. Ok, but what kind of serialization?
First, CodeFluent checks to see if the type implements the little known “IBinarySerialize” (from the Microsoft.SqlServer.Server namespace) interface. This is especially useful for SQL 2008 types (see this article http://forums.softfluent.com/default.aspx?g=posts&t=40 for more details).
Then, CodeFluent Entities uses what has been configured on the property. This is defined by the model attribute ‘persistenceSerializationMode’. The default value is ‘Binary | ArrayOfBytesType’. It means the .NET instance will be serialized using .NET standard serialization (not XML, not SOAP), and stored as an array of bytes.
Thus, our rectangle will be serialized as an array of bytes. With this model, the corresponding “Bounds” column data type in the database will be TEXT/NTEXT (SQL server) or BLOB (Oracle).
With the following C# using the generated BOM (note we use the standard .NET Rectangle type, as expected):
Shape shape = new Shape(); shape.Bounds = new System.Drawing.Rectangle(10, 20, 30, 40); shape.Save();
We will have this in SQL Server:
Now, we could also declare this
<Shape> <Id /> <Bounds typeName="System.Drawing.Rectangle" persistenceSerializationMode="Xml | StringType" /> </Shape>
Because we used Xml combined with StringType, the corresponding “Bounds” column data type in the database will be XML (supported in SQL Server 2005 or higher and Oracle Database 10 or higher). With the same C# code, we will have this in SQL Server:
If we click on the Xml column, we can see the Rectangle instance was automatically serialized as plain Xml, thanks to CodeFluent Entities:
Now, let’s suppose we want to load all our shapes ordered – server side – by the rectangle area, or we want to write some back end process that need access to the inner properties of the stored rectangles. What we want to do is have the X, Y, Width and Height properties available in the persistence layer. The solution is to declare the Rectangle .NET type as an existing lightweight entity. This is how we do this:
<cf:project xmlns:cf="http://www.softfluent.com/codefluent/2005/1" defaultNamespace="Test" assemblyPaths="System.Drawing"> <Rectangle namespace="System.Drawing, System.Drawing"> <X /> <Y /> <Height /> <Width /> </Rectangle> <Shape> <Id /> <Bounds typeName="System.Drawing.Rectangle" /> <cf:method name="LoadOrderedByBoundsSize" body="load() raw"> SELECT * FROM Shape ORDER BY Bounds_Shape_Rectangle_Width * Bounds_Shape_Rectangle_Height </cf:method> </Shape> </cf:project>
In this model, you can see we declare a regular entity named “Rectangle” in the namespace System.Drawing. The ‘namespace’ attribute notation here includes the assembly name as well (without culture and version). Please note the project node also has an ‘assemblyPaths’ that helps CodeFluent Entities to determine if an entity is an existing type or not. The value of ‘assemblyPaths’ is just a comma separated list of physical assembly paths, or GAC names.
When an existing type is declared as an entity, this entity does not have the notion of key properties. You just need to declare what properties you want CodeFluent Entities to use when persisting an instance of it. These properties must exist and the name is case sensitive. In the case of Rectangle, X, Y, Height and Width are real properties of System.Int32 type. Rectangle also has Bottom or Left properties, but since they are redundant, we don’t declare them. The persistence type is automatically determined by CodeFluent using Reflection techniques.
In this example, the method is a RAW method because CodeFluent does not allow the * notation in an order by.
In the database we now have 4 columns representing the Bounds property. If we use the same previous C# code, this is what we have in the database:
Have fun with CodeFluent Entities!
CodeFluent Entities R&D team.
A new assembly is now part of the setup: CodeFluent.Runtime.Silverlight4.dll. It can be used right now for your Silverlight 4 projects, just like CodeFluent.Runtime.Silverlight3.dll (for SL3) and CodeFluent.Runtime.Silverlight.dll (for SL2).
It has exactly the same features as the previous ones.
Have fun with Silverlight 4!
CodeFluent Entities R&D team.