CodeFluent Entities: Writing a custom aspect
In the previous post, we’ve seen that CodeFluent Entities infers a meta-model from our model and that we could interact with this meta-model to apply application wide changes. In this post we’ll see how ![]()
Step 1: Writing your aspect
As an example we’ll write an aspect which will add a “IsDeleted” property on all entities by default.
First of all, we added a new class library project named “Demo.Aspects” to our solution and added the following references: CodeFluent.Model.dll, CodeFluent.Model.Common.dll and CodeFluent.Runtime.dll. Aspects can either be written in XML or in .NET. In my opinion, it’s easier to start writing aspects in .NET as you’ll have Visual Studio’s IntelliSense which will help you out using the API.
In practice, an aspect is a class implementing the IProjectTemplate interface. This interface contains a single method “Run” which takes as a parameter a “context”.
Here’s a sample implementation:
using System.Collections;
using System.Xml;
using CodeFluent.Model;
namespace Demo.Aspects
{
public class MyAspect: IProjectTemplate
{
public static readonly XmlDocument Descriptor;
public const string MyAspectNamespace = "http://www.mycompany.com/aspects/myaspect/2013/1";
static MyAspect()
{
Descriptor = new XmlDocument();
Descriptor.LoadXml(
@"<cf:project xmlns:cf='http://www.softfluent.com/codefluent/2005/1' defaultNamespace='MyAspect'>
<cf:pattern name='My Aspect' namespaceUri='" + MyAspectNamespace + @"' preferredPrefix='mya' step='Tables'>
<cf:message class='_doc'>This is some description for our custom aspect.</cf:message>
<cf:descriptor name='enable'
typeName='boolean'
category='My Custom Aspect'
targets='Entity'
defaultValue='false'
displayName='Add the MyCustomProperty'
description='Description for our custom descriptor.' />
</cf:pattern>
</cf:project>");
}
public XmlDocument Run(IDictionary context)
{
if (context == null || !context.Contains("Project"))
{
// we are probably called for meta data inspection
return Descriptor;
}
// the dictionary contains at least these two entries
Element = (XmlElement)context["Element"];
Project = (Project)context["Project"];
foreach (Entity entity in Project.Entities)
{
Property property = new Property();
property.Name = "IsDeleted";
property.TypeName = "bool";
entity.Properties.Add(property);
}
// we have no specific Xml to send back, but aspect description
return Descriptor;
}
}
The method returns a XmlDocument which is described above as a string. It could also be written on a separate file.
As you can see this XML defines the aspect’s name, its XML namespace, and how it extends the CodeFluent schema (here it adds a “mya:enable” attribute on entities, whose default value is false).
Step 2: Using your aspect
Compile the “Demo.Aspects” project.
In the solution explorer, select the “Aspects” folder and click “Add Existing Aspect…”. Browse for our Demo.Aspects.dll that we created previously and here’s what you should see:
Great! As you can see, information returned by our descriptor is properly parsed and displayed ![]()
Hit OK, and now by default all your entities should have an extra “IsDeleted” property added when the model is inferred, which means that a “IsDeleted” column will be created for all tables, all stored procedures will be updated to include this column, and it’s the same in the middle tier and the UI tier. You can view this by clicking on the “View Inferred Model” button available in the ribbon:
Useful Links
- Documentation: Aspects Overview
- Documentation: The CodeFluent Entities API
- Documentation: Writing an aspect (.NET)
Hope this helps,
Carl Anderson
-
November 16, 2012 at 3:18 pm | #1Custom Sub Producer Example « The CodeFluent Entities Blog