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: ,
Follow

Get every new post delivered to your Inbox.

Join 51 other followers