Archive

Archive for February, 2012

CodeFluent Entities: Attributes

February 23, 2012 1 comment

Using CodeFluent Entities you can define attributes on other concepts such as Entities, Methods or Properties and what gets really interesting is that the .NET Business Object Model Producer translates those CodeFluent Entities Attributes into actual .NET attributes Smile

Now say you want to specify some specific attributes on your generated .NET classes or data annotations on your properties, defining attributes in your model would be the way to go!

To do so select your concept such as a property and click on “Add Attribute” in the ribbon, the following dialog will show up:

image

In the attribute name set the full type name of your attribute such as System.ComponentModel.DataAnnotations.RequiredAttribute”.

Note: Setting the attribute class using the drop down list in the lower part of the form allows you to specify where this attribute should be placed in the generated classes. Default is in the entity class, but you can also place it in the service class, the service interface, or the proxy class.

In the screenshot below we defined a Required data annotation attribute on the Name property of our entity:

image

Then here’s the output after generating our model over:

[System.ComponentModel.DataAnnotations.RequiredAttribute()]
[System.ComponentModel.DefaultValueAttribute(default(string))]
[System.Xml.Serialization.XmlElementAttribute(IsNullable=true, Type=typeof(string))]
public string Name
{
    (…)

To specify a parameter to your attribute, go back to your model, select your attribute and click on the Arguments property in the property grid:

image

And let’s add an error message to our required attribute:

image

Generate over and here’s the result:

[System.ComponentModel.DataAnnotations.RequiredAttribute(ErrorMessage="Name is required")]
[System.ComponentModel.DefaultValueAttribute(default(string))]
[System.Xml.Serialization.XmlElementAttribute(IsNullable=true, Type=typeof(string))]
public string Name
{
    (…)

 

Carl Anderson

Meet us at DevWeek 2012!

February 22, 2012 Leave a comment

SoftFluent sponsors DevWeek  (UK’s biggest conference for developers)  taking place in London from March 26th to 30th 2012.

2012_devweek

We’ll hold a booth over there (next to our buddies from Infragistics) so come have a chat with us!

Categories: News Tags: ,

CodeFluent Entities: Connection Strings

February 21, 2012 Leave a comment

Fairly recently we had a big thread of questions regarding connection strings on our forums, so I thought I’d do a recap’ of how connection strings are handled in CodeFluent Entities.

First it’s important to separate two distinct stages:

  • generation time: the connection string used by your producer to generate code,
  • run time: the connection string used by your generated application.

 

At Generation Time

As mentioned in previous posts (see Environment Variables Support and Default Persistence Server), CodeFluent Entities uses a default connection string which is as follows:

Application Name=[DefaultNamespace];server=[DefaultPersistenceServer];database=[DefaultNamespace];Integrated Security=true;

  • [DefaultNamespace]: your CodeFluent Entities default namespace,
  • [DefaultPersistenceServer]: value of the CF_DEFAULT_PERSISTENCE_SERVER environment variable or “127.0.0.1” if not found.

As a consequence, by setting the CF_DEFAULT_PERSISTENCE_SERVER environment variable (see Default Persistence Server for more info), you won’t even have to specify connection strings to build your applications on your development environment.

What’s even better, is that if you’re working as a team on the same application, if each member specified its own persistence server, they won’t even have to check-out and modify the model to build it in their respective environment.

This being said, in some situations, you might have to set a specific connection string to build somewhere else than on your default persistence server. To do so, you’ve got several options:

  • On your project, set the “Default Connection String” property to the default connection string to use (if none specified, the default one is used)
  • Or you can specify it producer by producer (if no connection string set, the one defined at the project level is used)

 

At Run Time

Now that you generated your application, it can run anywhere, and connect to any persistence server.

Once again, just like at generation time, the same connection string is used by default:

Application Name=[DefaultNamespace];server=[DefaultPersistenceServer];database=[DefaultNamespace];Integrated Security=true;

So likewise, if you specified the CF_DEFAULT_PERSISTENCE_SERVER environment variable on your machine, you won’t have to define a connection string.

If your application runs on a machine without this variable, or if you want it to use another persistence server explicitly, you’ll need to set its connection string in its application configuration file (app.config for a desktop app, or web.config for a web app). Here’s the corresponding documentation article illustrating how to do it: Application Configuration.

Another point of interest is that you can reuse connection strings defined in the standard .NET <connectionStrings> element.

Example:

<configuration>
  <configSections>
    <section name="Sample" type="CodeFluent.Runtime.CodeFluentConfigurationSectionHandler, CodeFluent.Runtime"/>
  </configSections>
  <connectionStrings>
    <add name="SqlServer" connectionString="server=MYSERVER;database=Sample;Integrated Security=true" />
    <add name="SqlServerExpress" connectionString="server=MYSERVER\SQLEXPRESS;database=Sample;Integrated Security=true" />
  </connectionStrings>
  <Sample connectionString="{SqlServerExpress}" />
</configuration>

The example above we’ll use the connection string named “SqlServerExpress”.

Another point of interest is that you can also use environment variables as the connection string name, so that based on an environment variable you can go pick one connection string or the other. For instance, depending on the local machine name, you could connect to one persistence server or another:

<configuration>
  <configSections>
    <section name="Sample" type="CodeFluent.Runtime.CodeFluentConfigurationSectionHandler, CodeFluent.Runtime"/>
  </configSections>
  <connectionStrings>
    <add name="Foo" connectionString="server=MyServer1;database=Sample;Integrated Security=true" />
    <add name="Bar" connectionString="server=MyServer2;database=Sample;Integrated Security=true" />
  </connectionStrings>
  <Sample connectionString="{%COMPUTERNAME%}" />
</configuration>

In the example above, if we’re on the “Foo” machine we’ll connect to “MyServer1” whereas when we’re on the “Bar” machine, we’ll connect to the server “MyServer2”.

 

Hope this helps,

Carl Anderson

February 20th 2012 Links: Windows 8, Office 15, Azure, Windows Phone, Tips

February 20, 2012 1 comment

The latest batch of our link-listing series:

Windows 8

Windows 8 logo revealed

“It’s a window … not a flag.”

The Whole World Will Finally Get To Look At Windows 8 On February 29th

On February 29, Microsoft will finally release the Consumer Preview, a partly-finished beta, to the entire world. It’s announcing the preview at an event at Mobile World Congress in Barcelona.

 

Office 15

Office 15 Begins Technical Preview

One step closer to the beta program.

 

Windows Azure

Microsoft’s Windows Azure Active Directory plans takes shape

Interesting Smile

Announcing Reduced Pricing on SQL Azure and New 100MB Database Option

Yay!! Price reductions!!

 

Windows Phone

Windows Phone Design Guidelines on MSDN

Looking  for design guidelines on the Windows Phone platform? Microsoft recently released official ones in the MSDN. A must read for Windows Phone developers!

 

Coding Tips

When can I use…
Wondering if you can use this HTML5 tag, or CSS attribute in specific browsers? Check-out this web site as it provides compatibility tables for support of HTML5, CSS3, SVG and more in desktop and mobile browsers.
Debugger Canvas

Debugger Canvas is a new user experience for the debugger in Visual Studio Ultimate. It pulls together the code you’re exploring onto a single pan-and-zoom display. As you hit breakpoints or step into code, Debugger Canvas shows just the methods that you’re debugging, with call lines and local variables, to help you see the bigger picture.

Carl Anderson

CodeFluent Runtime now available on NuGet Gallery

February 17, 2012 1 comment

The CodeFluent Runtime is a library of utilities which is usable across all types of .NET applications (WPF, WinForms, ASP.NET, console, service, etc.) and aims to ease the developer’s life. Until now it was only distributed as part of CodeFluent Entities, but starting today it is now shipped as a NuGet package on the NuGet Gallery!

This means that from now on, you can leverage utilities of the runtime – such as its JSON serializer/deserializer for instance Winking smile – from any .NET project regardless if you’re using CodeFluent Entities or not.

If you’re new to NuGet, here’s an overview: http://docs.nuget.org/docs/start-here/overview

Once you have NuGet, search for the CodeFluentRuntime package and add it to your project: it’s free Smile
Update: The CodeFluent Runtime package was replaced by the CodeFluent Runtime Client package (free as well, containing the same features, but lighter and supporting .NET Framework 4 Client Profile). Therefore, search for the new package “CodeFluentRuntimeClient” instead!

image

Cheers,

Carl Anderson

CodeFluent Entities: Writing a Template Generating One File Per Entity

February 16, 2012 1 comment

Following the previous post “Generating Custom Code For All Entities” a colleague showed me the greatest way ever to iterate on a collection of concepts and generate text a file for each from a template, so I thought I’d share it Smile

In this post we’ll write a template to generate a C# file per entity extending the one generated by the Business Object Model producer. The generated file should look like this one:

namespace Sample
{
    public partial class Customer
    {
        public static Customer LoadFromLob(string entityKey)
        {
            // TODO: load from external LOB
        }
    
        public void SendToLob()
        {
            // TODO: save current instance to external LOB
        }
    }
}

 

To generate code like the one above I created a template file named “[Template]entity.tpl”.

Note: The “[Template]” prefix is important as it indicates the producer to run the template. Other than that, the rest of the name doesn’t matter as we’ll name our output files <EntityName>.g.cs and this will be done in the template.

Here’s my template:

[%@ template enumerable='Producer.Project.Entities' enumerableItemName="entity" enumerableTargetPathFunc='Path.Combine(Path.GetDirectoryName(TargetPath), entity.Name) + ".g.cs"' %]
//------------------------------------------------------------------------------
// <auto-generated>
//     This code was generated by the Template Producer.
//
//     Changes to this file may cause incorrect behavior and will be lost if
//     the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------

namespace [%=entity.Namespace%]
{
    public partial class [%=entity.Name%]
    {
        public static [%=entity.Name%] LoadFromLob(string entityKey)
        {
            // TODO: load from external LOB
        }
    
        public void SendToLob()
        {
            // TODO: save current instance to external LOB
        }
    }
}

Instead of all the code which we used to have I now have a single line which will have the exact same effect. Here’s a description of what it does:

  • the enumerable attribute takes an IEnumerable as an input. In our case, I’ve set it to take as input all entities of my project. This is possible as all producers have a Project property corresponding to the model inferred from your model.
  • the enumerableItemName attribute corresponds to the item name which I named “entity” as I’m enumerating on all entities. That’s basically the variable name of my foreach, and that’s how I can use the “entity” variable in the rest of my template.
  • the enumerableTargetPathFunc is a code snippet to be called to compute the target path of the generated file. This is thanks to this snippet that I’m generating files named as “<EntityName>.g.cs”.

Running my new template, here’s the result:

//------------------------------------------------------------------------------
// <auto-generated>
//     This code was generated by the Template Producer.
//
//     Changes to this file may cause incorrect behavior and will be lost if
//     the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------

namespace Sample
{
    public partial class Customer
    {
        public static Customer LoadFromLob(string entityKey)
        {
            // TODO: load from external LOB
        }
    
        public void SendToLob()
        {
            // TODO: save current instance to external LOB
        }
    }
}

 

Carl Anderson

Categories: Templates Tags: ,

CodeFluent Entities: Generating Custom Code For All Entities

February 15, 2012 3 comments

We often have questions on our forums of CodeFluent Entities users who’d like to add custom methods to all entities of their project.

A convenient way to do this is by writing a template of those custom methods and run them on all entities, and this is what we’ll see in this post.

Scenario

Say I have some line of business, external to my application, but with which every now and then I want to be able to synchronize my generated classes. As a consequence, I’d like all my entity classes to have two extra methods: a SendToLob and LoadFromLob.

Solution

To do so we’re going to write a template which, for each entity, will add those two methods in a partial class, extending the generated code. To do so we’ll create a single template which will create one .CS file for each entity.

Here’s our template (named “[Template]entity.g.cs”):

[%@ template language="CSharp" output="false"%]
[%@ namespace name="System" %]
[%@ namespace name="CodeFluent.Model" %]
[%@ namespace name="CodeFluent.Producers.CodeDom" %]
[%@ namespace name="CodeFluent.Model.UI" %]
[%@ namespace name="CodeFluent.Model.UI.ControlDefinitions" %]
[%@ namespace name="CodeFluent.Producers.CodeDom.UI" %]
[%@ namespace name="System.IO" %]
[%

Entity entity = null;
if (Context["inTemplate"] == null)
{
    Context["inTemplate"] = true; // anything would do, other than null
    foreach(Entity e in Producer.Project.Entities)
    {
        // build a new target path & re-run ourselves
        string targetPath = Path.Combine(
            Path.GetDirectoryName(TargetPath),
            Path.GetFileName(TargetPath).Replace("entity", e.Name));
        using (GeneratedFile file = new GeneratedFile(Producer.Project, targetPath))
        {
            if ((file.HasBeenChanged) && ((e.ProductionFlags & ProductionFlags.Overwrite) == 0))
            {
                Producer.RaiseProduction(Producer, file.CreateFileSkipEvent("entity.g.cs"));
                continue;
            }

            // note: we don't care about the output="false" here
            Producer.RaiseProduction(Producer, ProductionEventArgs.CreateFileTemplateGenerateEvent(targetPath, Template.FilePath));
            file.Open(Producer, Producer.OutputEncoding);

            // add the entity to the context
            Context["entity"] = e;

            // update targetPath
            Context["TargetPath"] = targetPath;

            // go recursive, and this will jump to the else part of this file
            Template.Run(file.Writer, Context);
        }
    }
}
else
{
    entity = (Entity)Context["entity"];
%]
namespace [%=entity.Namespace%]
{
    public partial class [%=entity.Name%]
    {
        public static [%=entity.Name%] LoadFromLob(string entityKey)
        {
            // TODO: load from external LOB
        }

        public void SendToLob()
        {
            // TODO: save current instance to external LOB
        }
    }
}
[% }%]

The first part of the template iterates on all entities, and re-runs itself to create a file where the “entity” file name was replaced by the actual entity name. The second part of the template is the actual code to be placed in the generated file.

Then:

  • Add an instance of the Template Producer to your model,
  • Set its source directory to point to the directory containing our [Template]entity.g.cs file,
  • Set its target directory to be the same as your Business Object Model Producer so the generated classes will be in the same directory.

You’re now ready to go, generate over!

Result

Extra files were generated (one per entity) extending your already existing generated classes:

image

And here’s the content of the Customer.g.cs file:

namespace Sample
{
    public partial class Customer
    {
        public static Customer LoadFromLob(string entityKey)
        {
            // TODO: load from external LOB
        }

        public void SendToLob()
        {
            // TODO: save current instance to external LOB
        }
    }
}

Remarks

Drawbacks of this method are that:

  • it creates one extra file per entity,
  • if entity classes are generated in subfolders (e.g. multiple namespaces) it will require extra code to handle.

Other options to obtain the same output but without those drawbacks could be to:

  • Generate a single class file extending all classes (a little ugly, yet so effective Smile)
  • Create a CodeFluent Aspect instead of using templates to add code snippets to all entities!

Hope this helps,

Carl Anderson

Categories: Templates Tags: ,

What is a CodeFluent Entities model?

February 14, 2012 1 comment

CodeFluent Entities is a unique product integrated into Visual Studio 2008/2010/vNext which allows you to generate components such as scripts (e.g. T-SQL, PL/SQL), code (e.g. C#, VB), web services (e.g. WCF, ASMX) and UIs (e.g. ASP.NET, SharePoint, WPF).

The code generation process is model-first and continuous: from your declarative model, a meta-model will be inferred which code generators will then translate into code. Over 20 code generators (a.k.a. “producers”) are provided “out of the box” and can be combined to create your own application following your desired architecture, using your desired technologies.

Since your application development is driven from this model, your business logic is decoupled from the technology and allows you to absorb changes faster and smoother: apply changes in your model to update all your layers consistently, or add/switch technology by changing your used code generators.

 

So, since everything is driven from this model, what is, technically speaking, a CodeFluent Entities model?

image

Physically, a CodeFluent Entities project is a “package”, that is to say a bunch of files, which we call “parts”. CodeFluent Entities Parts can be of several types:

  1. Model parts: XML or CFP files containing a <cf:project …/> root element,
  2. Surface model parts: XML or CFP files containing a <cf:project …/> root element but reserved to store descriptions of surfaces,
  3. Resource parts: any other file referenced by the <cf:import …/> element, which are not files of type 1 and 2 (yes you can reference images to use them as blobs for instance).

When you load your CodeFluent Entities project in Visual Studio, there are several representations of the model which will coexist:

  1. An in-memory representation (an instance of the Project class and all what’s linked to it),
  2. A graphic representation on one or several opened surfaces,
  3. A XML representation on one or several opened XML files (or CFP).

image

 

What happens when I save?

When you save using Visual Studio’s “Save” menu item, it will save the “current document”, whatever this document may be. So:

  1. Saving using this menu item on an active & opened surface will just save the corresponding “surface model part”. It is equivalent to the  “Save Layout” menu item.
  2. Saving using this menu item on a XML or CFP model part (the active document is then the actual XML file) is completely different. CodeFluent Entities will in fact read the saved model part (XML or CFP), parse it as an independent model, and try to merge it with the current in-memory representation. That’s what is technically called a “part refresh”.

There are then cases when this ”part refresh” can fail:

  • If the file contains XML syntax errors (e.g. missing bracket or tag),
  • If the file is incorrect on a model level (e.g. an entity is already declared in another part or a key is missing)
  • For some other reason!

To troubleshoot this last type of errors, you can use Visual Studio’s “Error List” window  in which CodeFluent Entities will print its errors, including the line number if any.

image

 

Simon Mourier & Carl Anderson

CodeFluent Entities: SharePoint Web Part Producer

February 10, 2012 2 comments

In previous posts, we’ve introduced the SharePoint Web Part Producer, shown its output, and that you could customize forms. In this post we’ll show you how to generate web parts Smile

To generate web parts, add the SharePoint Web Part Producer to your project by clicking “Add new producer” on the “Producers” folder in Visual Studio’s Solution Explorer, expand the Web Producers node and select it:

image

The SharePoint Web Part producer provides two main types of features:

  • code generation features,
  • deployment features.

You can use it to generate code, compile it and deploy it on a SharePoint server in the same run, however here since we want to be able to view and extend the code, compile with Visual Studio and deploy ourselves, we’re going to disable those deployment features.

Here’s a sample configuration:

image

Properties I changed are in bold:

  • Source Production > Target Directory (mandatory): I’m making it point to my class library project containing my generated .NET classes
  • Deployment > Copy Binaries: Set it to false, we’ll compile with VS so the producer has no binary to deploy yet,
  • Deployment > Update [trust].config: Set it to false, same as before, for now we’re developing, we’re not bothering with deployment stuff,
  • Deployment > Update web.config: Set it to false, same as [trust].config,
  • Site Creator > Produce MsBuild Task Files: The site creator feature is to create a document library on the SharePoint server to test our generated web parts, set it to false for now,
  • Site Creator > Produce Source Files: set it to false as well.

Build your project over and….ooops! We get the following error:

CF5519: The SharePoint WebParts producer needs the ‘SoftFluent.AssociationManage’ pattern to be included in the project.

Correct, the AssociationManage Aspect is needed by the SharePoint producer as it adds many-to-many management features which are required in the generated UI.

While we’re at it, I’d also recommend you add the AutoFormattable aspect to your project as in the generated UI, for one to many relations, you’ll get a preview of related data if any instead of just the number of related items.

image

Generate over, and there you go: you’ll see that custom web parts were generated:

image

Carl Anderson

Exploring the CodeFluent Runtime: AutoObject

February 8, 2012 Leave a comment

Following our “Exploring the CodeFluent Runtime“ post series, I thought I’d share with you another cool class available in the CodeFluent Runtime which is the AutoObject class.

The AutoObject class is a light class which implements INotifyPropertyChanged and IDataErrorInfo so you can easily and quickly create classes data-binding and validation friendly classes.

Here’s how it works: say you need a small technical class for UI purposes. You want it to support data-binding and to raise an event when a property is changed, plus since your working in the UI, you might at some point need to validate user input. Instead of implementing those interfaces myself, I can derive from the AutoObject class which will provide those features for me.

Data-Binding (INotifyPropertyChanged):

Across .NET platforms (e.g. Windows Forms, WPF) a lot of .NET controls provided by Microsoft or third parties (e.g. Infragistics) use this interface to update the UI to reflect changes in the model. Here’s how to use the AutoObject to benefit from those features:

public class CustomerLight : AutoObject
{
    public CustomerLight()
    {
    }

    public string FullName
    {
        get
        {
            return GetProperty();
        }
        set
        {
            SetProperty(value);
        }
    }

    public string FullAddress
    {
        get
        {
            return GetProperty();
        }
        set
        {
            SetProperty(value);
        }
    }

}

And that’s it! Since the AutoObject implements the INotifyPropertyChanged interface for me, I can data-bind my UI to it easily. In fact, here’s a sample console application which prints received PropertyChanged events on the command line:

class Program
{
    private static CustomerLight _cv;

    static void Main(string[] args)
    {
        _cv = new CustomerLight();
        _cv.PropertyChanged += new PropertyChangedEventHandler(OnCustomerLightPropertyChanged);

        Console.WriteLine("Type-in customer full name:");
        _cv.FullName = Console.ReadLine();
        Console.ReadKey();
    }

    static void OnCustomerLightPropertyChanged(object sender, PropertyChangedEventArgs e)
    {
        Console.WriteLine("PropertyChanged: " + e.PropertyName);
    }
}

Here’s the result:

Type-in customer full name:
John Doe
PropertyChanged: FullName

Data Validation (IDataErrorInfo):

It’s exactly the same as for INotifyPropertyChanged, lots of UI control provide nice UI validation features if you implement this interface, and here’s how to do it using the AutoObject:

public class CustomerLight : AutoObject
{
    public CustomerLight()
    {
    }

    public string FullName
    {
        get
        {
            return GetProperty();
        }
        set
        {
            SetProperty(value);
        }
    }

    public string FullAddress
    {
        get
        {
            return GetProperty();
        }
        set
        {
            SetProperty(value);
        }
    }

    protected override void Validate(IList errors, string memberName)
    {
        // If no memberName, validate all members.
        if (string.IsNullOrEmpty(memberName) || memberName == "FullName")
        {
            if (FullName.IndexOfAny(new char[] { '!', '*', '@', '?' }) != -1)
            {
                errors.Add("Invalid name: the following characters are considered invalid: '!*@?'.");
            }
        }
    }
}

And we’ll update our console application to retrieve the validation error and print it if any:

static void OnCustomerLightPropertyChanged(object sender, PropertyChangedEventArgs e)
{
    Console.WriteLine("PropertyChanged: " + e.PropertyName);

    string error = ((IDataErrorInfo)_cv).Error;
    if (string.IsNullOrEmpty(error))
        return;

    Console.WriteLine(error);
}

And here’s the result:

Type-in customer full name:
test*test
PropertyChanged: FullName
Invalid name: the following characters are considered invalid: ‘!*@?’.

Hope this helps,

Carl Anderson

Follow

Get every new post delivered to your Inbox.

Join 41 other followers