Quantcast
Channel: SoftFluent – The CodeFluent Entities Blog
Viewing all 125 articles
Browse latest View live

[Pet Shop Reloaded] Using the generated code – Part 1

$
0
0

In this article, we will talk about using the code generated by CodeFluent Entities and Entity Framework. On the first part of this article we will focus on using the code generated by CodeFluent Entities then on an upcoming article we will see how to use the code generated by Entity Framework and the differences between the two approaches.

Use of CodeFluent Entities generated code

In order to use the code generated by CodeFluent Entities do not forget to add a reference to our class library project which contains the generated files as well as a reference to the “CodeFluent.Runtime” and the “CodeFluent.Runtime.Web”. Those DLL can be found in the installation directory of CodeFluent Entities, by default in “C:Program Files (x86)SoftFluentCodeFluentx64”.

First of all, we need to modify the “Web.config” file according to the screenshot below to add our connection string, add the generated blob handler in the “HttpHandler” section and register membership and role providers generated by CodeFluent Entities which are based on the AspNet membership and role providers.

9

In order for our blob handler to work we need to add a new route to be ignored in our “RouteConfig.cs” file as it is showed in the code below.

 routes.IgnoreRoute("{handler}.ashx");

Once our “Web.config” file is set up, our web application is able to reach our database, display images stored in, and use generated providers.

We are now able to create a controller and a view associated to this controller to show how it works.

Therefore, I will create a “CategoryController” containing an “Index” ActionResult method which will use our custom method to load products by their category name.

Once our “Web.config” file is set up, our web application is able to reach our database, display images stored in, and use generated providers.

We are now able to create a controller and a view associated to this controller to show how it works.

Therefore, I will create a “CategoryController” containing an “Index” ActionResult method which will use our custom method to load products by their category name.

[HttpGet]
public ActionResult Index(string name)
{

ProductCollection products = ProductCollection.LoadByCategoryName(name);

if (products != null && products.Count != 0){

ViewBag.CategoryName = name;

return View(products);

}

else if (products != null && products.Count == 0){

ViewBag.CategoryName = "No such category";

return View(products);

}

else

return RedirectToAction("Index", "Home");

}

As you can see in the code above, we are getting all the matching products from our database and we returning this ProductCollection to our view.

Before going further, we will take a look to what was generated inside this “ProductCollection” class focusing on the “LoadByCategoryName” method.

[System.ComponentModel.DataObjectMethodAttribute(System.ComponentModel.DataObjectMethodType.Select, true)]

public static PetShopReloaded.ProductCollection LoadByCategoryName(string category)

{

PetShopReloaded.ProductCollection ret = PetShopReloaded.ProductCollection.PageLoadByCategoryName(int.MinValue, int.MaxValue, null, category);

return ret;

}

public static System.Data.IDataReader PageDataLoadByCategoryName(CodeFluent.Runtime.PageOptions pageOptions, string category)

{

if ((category == default(string)))

{

throw new System.ArgumentNullException("category");

}

CodeFluent.Runtime.CodeFluentPersistence persistence = CodeFluentContext.Get(PetShopReloaded.Constants.PetShopReloadedStoreName).Persistence;

persistence.CreateStoredProcedureCommand(null, "Product", "LoadByCategoryName");

persistence.AddParameter("@category", category);

if ((pageOptions != null))

{

System.Collections.IEnumerator enumerator = pageOptions.OrderByArguments.GetEnumerator();

bool b;

int index = 0;

for (b = enumerator.MoveNext(); b; b = enumerator.MoveNext())

{

CodeFluent.Runtime.OrderByArgument argument = ((CodeFluent.Runtime.OrderByArgument)(enumerator.Current));

persistence.AddParameter(string.Format("@_orderBy{0}", index), argument.Name);

persistence.AddParameter(string.Format("@_orderByDirection{0}", index), ((int)(argument.Direction)));

index = (index + 1);

}

}

System.Data.IDataReader reader = CodeFluentContext.Get(PetShopReloaded.Constants.PetShopReloadedStoreName).Persistence.ExecuteReader();

return reader;

}

CodeFluent Entities automatically generates “LoadBy” methods in collection classes for each entity relationship. For example, in the “ProductCollection” class we have a “LoadByCategory” method, as a Product has a relation with Category. We have also defined a “LoadByCategoryName” method to meet our specific needs. This method was generated using CFQL which is a platform independent language (http://blog.codefluententities.com/?s=cfql).

image

You can see that the code generated by CodeFluent Entities is clear and intelligible. Plus, if your business needs requires something really specific you can still extend what was generated by CodeFluent Entities since all the classes generated are partial classes. Therefore, you can focus on what matter for you and your application and not on the plumbing code.

CodeFluent Entities also generates methods to create, modify and delete data. Regarding creation or modification, a “Save” method is provided. This method will either save modifications made to an object or create this one if it doesn’t exist and it can be used as shown in the code sample below.

//Creation sample
Product product = new Product() { Name = "Demo" };
product.Save();

//Update sample
Product product = Product.Load(MyProductId);
product.Save();

For deletion, a “Delete” method is provided by CodeFluent Entities, a sample is shown below.

//Delete sample
Product product = Product.Load(MyProductId);
product.Delete();

CRUD methods are generated by default by CodeFluent Entities for all entities.

Taking for example the view where we show our items, we just want to display the content of the “ProductCollection” we passed from our controller. Therefore, we are creating a view which have a model type of “ProductCollection”. This view also uses the layout of the web application. Since we have passed a collection we need an enumerator, in this case we are using a “foreach”, to display its content. We are also adding some style to make it look nicer.

@model PetShopReloaded.ProductCollection

@{

Layout = "~/Views/Shared/_Layout.cshtml";

}

<h2 style="color: #444444;">@ViewBag.CategoryName</h2>

@foreach (var item in Model) {

<a href="@Url.Action("Index", "Product", new { item.Category.EntityDisplayName, item.Name })">

<p>@item.Name</p>

<img id="@item.Id" src='@(Request.ApplicationPath + CodeFluent.Runtime.Web.UI.BinaryLargeObjectHttpHandler.BuildUrl(null, CodeFluent.Runtime.Web.UI.WebControls.BinaryLargeObjectUrlType.Image, "PetShopReloaded.Product", "Product_Image", null, null, null, null, null, -1, -1, 0, new object[] { item.Id }))' style="width: 100%; height: 200px; margin:0; padding:0;"/>

<p style="text-align:justify; width: 278px; padding: 6px; height:35px; margin: 0; font-size: 9pt;">@item.Description</p>

</a>

}

As you can see, the “src” property of the “img” tag isn’t a simple variable. Since our images are stored in the database as BLOB’s as we said earlier we need an http handler. This BLOB handler was also generated by CodeFluent Entities.

public partial class HttpHandler : CodeFluent.Runtime.Web.UI.BinaryLargeObjectHttpHandler

{

private CodeFluent.Runtime.CodeFluentContext _context;

public override CodeFluent.Runtime.CodeFluentContext CodeFluentContext

{

get

{

if ((this._context == null))

{

if ((this.EntityClrFullTypeName == "PetShopReloaded.Item"))

{

this._context = CodeFluentContext.Get(PetShopReloaded.Constants.PetShopReloadedStoreName);

return this._context;

}

if ((this.EntityClrFullTypeName == "PetShopReloaded.Product"))

{

this._context = CodeFluentContext.Get(PetShopReloaded.Constants.PetShopReloadedStoreName);

return this._context;

}

this._context = CodeFluentContext.Get(PetShopReloaded.Constants.PetShopReloadedStoreName);

}

return this._context;

}

}

public override CodeFluent.Runtime.BinaryServices.BinaryLargeObject LoadBinaryLargeObject(System.Web.HttpContext context, string propertyName, object[] identifiersValues)

{

if ((this.EntityClrFullTypeName == "PetShopReloaded.Item"))

{

PetShopReloaded.Item Item = PetShopReloaded.Item.Load(((int)(ConvertUtilities.ChangeType(identifiersValues[0], typeof(int), -1))));

if ((Item == null))

{

return null;

}

if ((propertyName == "Item_Image"))

{

return Item.Image;

}

}

if ((this.EntityClrFullTypeName == "PetShopReloaded.Product"))

{

PetShopReloaded.Product Product = PetShopReloaded.Product.Load(((int)(ConvertUtilities.ChangeType(identifiersValues[0], typeof(int), -1))));

if ((Product == null))

{

return null;

}

if ((propertyName == "Product_Image"))

{

return Product.Image;

}

}

return null;

}

}

Remembering the model of our application you will notice that this generated BLOB handler will be able to handle image from “Product” and “Item” tables, which also are the only entities where we defined properties of type “image”. Also you can check-out the Blob http Handler article for more information.

To conclude, we can say that CodeFluent Entities provides ready-to-use code for you developers allowing you to focus on the application you are working on.

NB. For our application Pet Shop Reloaded we have used the generated BOM classes in a Web context (ASP .NET MVC), but know that you can also use it in other contexts like a WPF or a Windows Forms application.

Cheers,

The SoftFluent Team.



[Pet Shop Reloaded] Using the generated code – Part 2

$
0
0

In the previous article, we talked about using the code generated by CodeFluent Entities. On this one, we will first focus on the code generated by Entity Framework then we will summarize in a conclusion what is provided by the two solutions.
 

I – Use of Entity Framework generated code

In order to use the code generated by Entity Framework we will need to have some assemblies referenced in our project like “System.Data.Entity”, “EntityFramework”. Nevertheless, in our case we choose an ASP.NET MVC project and those are included out-of-the-box in the solution.

First of all, we have seen in the previous article that CodeFluent Entities generates out-of-the-box a BLOB handler for our images stored in the database. Obviously, Entity Framework doesn’t generate it for us, therefore we have to create our own BLOB handler.

To do so, we will add a new .ashx file at the root of our solution named “ImageHandler.ashx”. This file will contain the following code.

public class ImageHandler : IHttpHandler
{
  public void ProcessRequest(HttpContext context)
  {
    ModelContainer _db = new ModelContainer();
    string idStr, entityType;
    int id;

    if ((idStr = context.Request.QueryString.Get("ID")) != null && (entityType = context.Request.QueryString.Get("type")) != null && int.TryParse(idStr, out id))
    {
      if (entityType == "product")
      {
        Product product = _db.Product.Single(p => p.Id == id);
        context.Response.Clear();
        context.Response.ContentType = "image/jpg";
        context.Response.BinaryWrite(product.Image);
        context.Response.End();
      }
      else if (entityType == "item")
      {
        Item item = _db.Item.Single(i => i.Id == id);
        context.Response.Clear();
        context.Response.ContentType = "image/jpg";
        context.Response.BinaryWrite(item.Image);
        context.Response.End();
      }
    }
  }

  public bool IsReusable
  {
    get
    {
      return true;
    }
  }
}

As you can see, our class inherits from “IHttpHandler”, and based on the type it will either return the product image or the item image.

Once the handler created we will need to modify the “Web.config” file to reference our “ImageHandler” according to the following code.

<configuration>
  . . .
  <system.webServer>
    . . .
    <handlers>
      <add name="ImageHandler" verb="*" path="*.ashx" type="EF.PetShopReloaded.WebApp.ImageHandler,EF.PetShopReloaded.WebApp" />
      . . .
    </handlers>
  </system.webServer>
  . . .
</configuration>

In order for our blob handler to work we need to add a new route to be ignored in our “RouteConfig.cs” file as it is showed in the code below.

routes.IgnoreRoute("{handler}.ashx");

Our “Web.config” file is set up, our web application is able to reach our database, display images stored in, and use generated providers.

To be able to request data stored we also needed to instantiate our “ModelContainer” thanks to the following code.

public static ModelContainer _db = new ModelContainer();

As we did in the previous article with the code generated thanks to CodeFluent Entities, we will create a “CategoryController” containing an “Index” ActionResult method which will be used to retrieve products based on their category name.

public class CategoryController : Controller
{
  [HttpGet]
  public ActionResult Index(string name)
  {
    var products = EF.PetShopReloaded.WebApp.MvcApplication._db.Product.Where(c => c.Category.Name == name).ToList();

    if (products.Count != 0)
    {
      ViewBag.CategoryName = name;

      return View(products);
    }
    else if (products.Count == 0)
    {
      ViewBag.CategoryName = "No such category";

      return View(products);
    }
    else
      return RedirectToAction("Index", "Home");
  }
}

Let’s focus on the line

var products = EF.PetShopReloaded.WebApp.MvcApplication._db.Product.Where(c => c.Category.Name == name).ToList();

We used LINQ-to-Entities to retrieve all the products by name, in this example this is a very simple query and maybe we won’t have any problem when trying to debug it. However when we have more complicated queries it will be harder to debug them if there is a problem, this because Entity Framework generate SQL code on the fly, so we will need to use a profiler tool to see the actual query that is sent to the SQL server.

Obviously we can also manipulate data thanks to the code generated by Entity Framework. As we have seen in the article treating about the creation of the model of the application with CodeFluent Entities we are able to create instances to add data at generation but such a feature isn’t provided by Entity Framework and we had to create data manually from code. Therefore, we will use these data creation scripts to illustrate how to manipulate data with Entity Framework.

Regarding data creation we will take as example the “CreateCategories” class which can be find under the “Data” folder. As you can see in the code below, we are adding new categories and persisting them by calling the “SaveChanges” method.

public class CreateCategories
{
  public CreateCategories(ModelContainer _db)
  {
    _db.Category.Add(new Category() { Name = "Birds", Description = "Birds" });
    _db.Category.Add(new Category() { Name = "Backyard", Description = "Backyard" });
    _db.Category.Add(new Category() { Name = "Bugs", Description = "Bugs" });
    _db.Category.Add(new Category() { Name = "Endangered", Description = "Endangered" });
    _db.Category.Add(new Category() { Name = "Fish", Description = "Fish" });

    _db.SaveChanges();
  }
}

In order to update data, we just need to get the category we want to modify, update its properties and finally call the “SaveChanges” method to persist changes.

//Update sample
Category category = _db.Category.Single(c =&gt; c.Name == "Birds");
category.Name = "New name";

_db.SaveChanges();

For deletion, a “Delete” method is provided by CodeFluent Entities, the sample below shows how to delete an entity with Entity Framework.

//Delete sample
_db.Category.Remove(selectedCategory);

_db.SaveChanges();

Taking for example the view where we show our items, we just want to display the content of the product list we passed from our controller. Therefore, we are creating a view which have a model type of “IEnumerable<EF.PetShopReloaded.WebApp.Models.Product>”. This view also uses the layout of the web application. Since we have passed a list we need an enumerator, in this case we are using a “foreach”, to display its content. As we did in the previous article we will once again add some style to make it look nicer.

@model IEnumerable<EF.PetShopReloaded.WebApp.Models.Product>

@{
    Layout = "~/Views/Shared/_Layout.cshtml";
}

<h2 style="color: #444444;">@ViewBag.CategoryName</h2>

@foreach (var item in Model) {
    <a class="category" href="@Url.Action("Index", "Product", new { item.Category.Description, item.Name })">
        <p class="categoryTitle">@item.Name</p>
        <img id="@item.Id" src="~/ImageHandler.ashx?ID=@item.Id&type=product" style="width: 100%; height: 200px; margin:0; padding:0;"/>
        <p style="text-align:justify; width: 278px; padding: 6px; height:35px; margin: 0; font-size: 9pt;">@item.Description</p>
    </a>
}

As you can see, the “src” property of the “img” tag isn’t a simple variable. Since our images are stored in the database as BLOBs, as we said earlier we need an http handler. In this case, the url is simpler than the one showed in the previous article but the handler is also less complex and flexible.

To conclude, we can say that CodeFluent Entities provides ready-to-use code for you developers allowing you to focus on the application you are working on.

 

II – Conclusion

In this two part article we have seen how to use code generated by both CodeFluent Entities and Entity Framework. We have seen that the code generated by CodeFluent Entities is more efficient, providing us ready-to-use and platform independent code whilst letting us focus on using it inside our application.

In the next article, we will talk more about statistics (e.g. number of lines of code, performances) to conclude this blog post series about “Pet Shop Reloaded”.

 

Cheers,

The SoftFluent Team.


Writing a custom CodeFluent Entities aspect to encrypt/decrypt columns values at runtime

$
0
0

Today, we will demonstrate how to automatically change the SQL code generated during the build process in order to encrypt and decrypt the values stored in the database columns. This is the answer to a very interesting question that was posted to stackoverflow recently: How to manage Encrypt* and Decrypt* TSQL functions on an entity property?

Let’s consider this model:

model

A card number is a sensible piece of information, so you should encrypt it before saving it in the database. Obviously, You should also be able to read it back and decrypt it.

Of course, with CodeFluent Entities, you can do it in the Business Object Model Layer generated BOM (C# or VB.NET) using OnAddSaveParameters and OnAfterReadRecord rules, but this post will demonstrate how it can be done directly in the database layer!

Microsoft SQL Server 2005 and higher provides two new useful functions: ENCRYPTBYPASSPHRASE and DECRYPTBYPASSPHRASE. These functions allow you to encrypt or decrypt data with a pass phrase. For example:

ENCRYPTBYPASSPHRASE(‘my super secret key’, ‘1234-5678-9012-3456-7890’) -- will write 0x01000000FFB251B13ADE1344597535490BDD7ABB4A5094CF24C211A63FFDD465052795A9 in the database

So all we need to do is to call ENCRYPTBYPASSPHRASE during saving (INSERT or UPDATE statements), and DECRYPTBYPASSPHRASE during loading (SELECT statements). A code such as this one for instance:

INSERT INTO [Test] ([Test].[Test_CardNumber])
   VALUES (ENCRYPTBYPASSPHRASE(@PassPhrase, @Test_CardNumber))

SELECT [Test].[Test_Id], CONVERT(nvarchar, DECRYPTBYPASSPHRASE(@PassPhrase, Test_CardNumber)) AS [Test_CardNumber]
   FROM   [Test]
   WHERE  [Test].[Test_Id] = @Id

Moreover, you’ll have to change the column type from string to varbinary to match the ENCRYPTBYPASSPHRASE return type.

In the CodeFluent Entities context, you’ll have to add the PassPhrase parameter to the stored procedure parameters, and to the BOM generated code.

Some theory

Before anything is actually generated, CodeFluent Entities parses the model and transforms it into a complete memory representation which contains Entities, Properties, Methods, Tables, Columns, Procedures, etc. The inference engine that does this transformation is using a pipeline that’s divided into steps. CodeFluent Entities Aspects can be introduced at any step, and are able to modify the model currently in memory, therefore influencing the next steps.

Here are the main steps of the inference pipeline:

pipeline

The most important thing to note here is the fact that each step processing uses what has been created in memory during the previous steps. So for example, if you add a property to an entity early enough during inference, this property will be used to create a column automatically, all standard methods will use this property, procedures – based on methods – will use this column automatically, and so on.

At the final stage, generators (a.k.a. ‘producers’ in CodeFluent Entities terminology) will transform this in-memory model into real code, files, etc.

You can read more about the inference pipeline at http://www.softfluent.com/documentation/Aspects_Overview.html

Enough theory… Let’s do it!

To make it short, an aspect is simply a .NET class that implements the CodeFluent.Model.IProjectTemplate interface (located in CodeFluent.Model.dll).
public interface IProjectTemplate
{
    XmlDocument Run(IDictionary context);
}

You’ll find some information about this interface in previous posts http://blog.codefluententities.com/2012/07/27/codefluent-entities-writing-a-custom-aspect/

An aspect usually declares a specific XML namespace it will use for its specific XML attributes that will be store alongside CodeFluent Entities ones. These attributes should also be declared. It’s not mandatory, but it’s cool if you want to use them directly in the graphical editor. To each descriptor will correspond a property grid line in the Visual Studio standard property grid.

public class EncryptAspect : IProjectTemplate
{
    public static readonly XmlDocument Descriptor;
    public const string Namespace = "http://www.softfluent.com/aspects/samples/crypt"; // this is my custom XML namespace
    private const string PassPhraseToken = "PassPhrase";
    public Project Project { get; set; }

    static EncryptAspect()
    {
        Descriptor = new XmlDocument();
        Descriptor.LoadXml(
        @"<cf:project xmlns:cf='http://www.softfluent.com/codefluent/2005/1' defaultNamespace='MyAspect'>
            <cf:pattern name='Encrypt Aspect' namespaceUri='" + Namespace + @"' preferredPrefix='ca' step='Start'>
                <cf:message class='_doc'> CodeFluent Sample Encrypt Aspect Version 1.0.0.1 - 2013/09/20 This aspect modifies Save and Load* procedures in order to call Sql Server         ENCRYPTBYPASSPHRASE / DECRYPTBYPASSPHRASE functions.</cf:message>
                <cf:descriptor name='encrypt'
                    typeName='boolean'
                    category='Encrypt Aspect'
                    targets='Property'
                    defaultValue='false'
                    displayName='Encrypt the property'
                    description='Determines if the property must be encrypted when saving to the database.' />
            </cf:pattern>
        </cf:project>");
    }
}

When the aspect runs, it needs to be notified whenever a property is added to an entity, anywhere in the model, in order to check whether it should be encrypted. If it should be encrypted, the entity should be modified accordingly.

The aspect should also be able to modify stored procedures code, once they are are generated. The step after stored procedures inference is ‘Categories’, so we need to handle this inference pipeline step as well:

public XmlDocument Run(IDictionary context)
{
    if (context == null || !context.Contains("Project"))
    {
        // we are probably called for meta data inspection, so we send back the descriptor xml<br />
        return Descriptor;
    }

    // the dictionary contains at least these two entries
    Project = (Project)context["Project"];

    // hook on new base entities, and hook on new properties
    Project.Entities.ListChanged += (sender, e) =>
    {
        if (e.ListChangedType != ListChangedType.ItemAdded)
            return;

        var entity = Project.Entities[e.NewIndex];
        if (!entity.IsPersistent)
            return;

        if (!entity.IsProjectDerived)
        {
            entity.Properties.ListChanged += OnPropertiesListChanged;
        }
    };

    Project.StepChanging += (sender, e) =>
    {
        if (e.Step != ImportStep.Categories)
            return;

        foreach (var procedure in Project.Database.Procedures.Where(procedure => procedure.Parameters[PassPhraseToken] != null))
        {
            UpdateProcedure(procedure);
        }
    };

    // we have no specific Xml to send back, but aspect description
    return Descriptor;
}

We have designed our aspect so it considers a property should be encrypted if the XML attribute “encrypt” (in the aspect XML namespace) is set to ‘true’ and if the property is persistent (e.g. available in the persistence layer). CodeFluent Entities provides methods to read XML file attributes easily. In this example, if the attribute “encrypt” is not defined or if its value is not convertible to a boolean value, the function will return false.

private static bool MustEncrypt(Property property)
{
    return property != null && property.IsPersistent && property.GetAttributeValue("encrypt", Namespace, false);
}

Now the OnPropertiesListChanged method applies the necessary changes whenever a new property is added:

  1. Check whether it must be encrypted
    private void OnPropertiesListChanged(object sender, ListChangedEventArgs e)
    {
        if (e.ListChangedType != ListChangedType.ItemAdded)
            return;
    
        var property = ((PropertyCollection)sender)[e.NewIndex];
        if (!MustEncrypt(property))
            return;
        ...
    }
  2. Change its persistence type to Binary
    property.DbType = DbType.Binary;
    property.MaxLength = 8000;
    
  3. Add an ambient parameter “PassPhrase” to the entity. This parameter will be used for all methods without explicitly declaring it on each one. The ambient parameter will automatically be inferred as a standard parameter for stored procedures, but it will get its value from a static property or method in the BOM. In this example it will get its value from a static parameterless arbitrarily named “GetPassPhrase” method, described further down the document. Its ambient expression (the expression to use in the WHERE part of the stored procedures) must be also set. Since this parameter is not really used as a filter clause in this example, let’s simply set it to “(1=1)” which is equivalent to a “NOP” in a WHERE SQL clause (i.e: WHERE (([Test].[Test_Id] = @Id) AND (1 = 1)))
    var passPhraseParameter = new MethodParameter
        {
            Name = PassPhraseToken,
            ClrFullTypeName = "string",
            Nullable = Nullable.False,
            Options = MethodParameterOptions.Ambient |
                        MethodParameterOptions.Inherits |
                        MethodParameterOptions.UsedForLoad |
                        MethodParameterOptions.UsedForSearch |
                        MethodParameterOptions.UsedForCount |
                        MethodParameterOptions.UsedForRaw |
                        MethodParameterOptions.UsedForSave,
            ModelName = "[" + Project.DefaultNamespace + ".PassPhrase.GetPassPhrase()]", // Note the brackets here. It means that code should not be verified by CodeFluent Entities; otherwise an existing property of the current entity is expected.
            AmbientExpression = "(1=1)"
        };
    
    property.Entity.AmbientParameters.Add(passPhraseParameter);
    

Ok, we applied the required changes to the future BOM, and now we need to update stored procedures before they get generated.

CodeFluent Entities creates an in-memory Abstract Syntax Tree (AST) to represent stored procedures. This AST is independent from the target database type, and can be modified during inference as well.

To update the in-memory stored procedures AST, you can visit (using a visitor pattern) this tree and modify it when needed. We will use literal expressions (ProcedureExpressionStatement.CreateLiteral(“Sql code”)) to create our ENCRYPT/DECRYPT Sql function calls. In this case, the generated code won’t be of course platform independent anymore. This aspect should be adapted if we wanted to use it on an Oracle, MySQL or PostgreSql database.

private static void UpdateProcedure(Procedure procedure)
{
    procedure.Parameters[PassPhraseToken].DefaultValue = null; // This means the passphrase must be provided, and cannot be null
    if (procedure.ProcedureType == ProcedureType.SaveEntity)
    {
        procedure.Body.Visit(s =>
        {
            var statement = s as ProcedureSetStatement;
            if (statement == null || statement.LeftExpression == null || statement.RightExpression == null || !MustEncrypt(statement.LeftExpression.RefColumn))
                return;

            string parameterName = statement.RightExpression.Parameter.Name;
            statement.RightExpression.Literal = ProcedureExpressionStatement.CreateLiteral(string.Format("ENCRYPTBYPASSPHRASE(@{0}, @{1})", PassPhraseToken, parameterName));
            statement.RightExpression.Parameter = null;

            // Column is of type varbinary but parameter must be of type string
            var parameter = procedure.Parameters[parameterName];
            if (parameter != null)
            {
                parameter.DbType = DbType.String;
            }
        });
        return;
    }
  
    procedure.Body.Visit(s =>
    {
        var statement = s as ProcedureSetStatement;
        if (statement == null || statement.LeftExpression == null || !MustEncrypt(statement.LeftExpression.RefColumn))
            return;

        statement.As = new ProcedureExpressionStatement(statement, ProcedureExpressionStatement.CreateLiteral(statement.LeftExpression.RefColumn.Column.Name));
        statement.LeftExpression.Literal = ProcedureExpressionStatement.CreateLiteral(string.Format("CONVERT(nvarchar, DECRYPTBYPASSPHRASE(@{0}, {1}))", PassPhraseToken, statement.LeftExpression.RefColumn.Column.Name));
        statement.LeftExpression.RefColumn = null;
    });
}

That’s it, the aspect is finished! But we want to use it in Visual Studio now…

Integrate the aspect in the visual modeler

To integrate your aspect, add a reference to the class library project that contains the aspect (it can be in the same solution):

integrate_aspect_in_modeler1

integrate_aspect_in_modeler2

Use the reference context menu to add an aspect (compiled) from this reference.

integrate_aspect_in_modeler3

The following dialog box will display what aspects are available in the compiled project, and what are the descriptors for the selected aspect:

integrate_aspect_in_modeler4

To use the aspect, a developer has to select the concept targeted by a given descriptor (Entity, Property, Method, etc.) and use the “Aspects and Producers Properties” tab in the Visual Studio standard property grid:

integrate_aspect_in_modeler5

Now you can build your model, add the logic to get the pass phrase, and enjoy :)

public static class PassPhrase
{
    public static string GetPassPhrase()
    {
        return "hello world";
    }
}

class Program
{
    static void Main(string[] args)
    {
        DemoEncrypt entity = new DemoEncrypt();
        entity.CardNumber = "0123-4567-8901-2346-5678";
        entity.Save();
        entity.Reload(CodeFluentReloadOptions.Default);
        Console.WriteLine(entity.Trace());
    }
}

The full source code is available here: DemoEncrypt.zip

Conclusion

With the power of CodeFluent Entities and approximately 180 lines of C# code, we have added the possibility to add database encryption to the columns of our choice and the tables of our choice. This aspect is 100% reusable across all our projects. Can you do this without CodeFluent Entities?

Cheers,
Gerald Barré


CodeFluent Entities (and CodeFluent Runtime Client) Zip File support

$
0
0

The CodeFluent.Runtime.dll (provided with the CodeFluent Entities commercial product) and the CodeFluent.Runtime.Client.dll (provided as a totally FREE nuget package) both contain a very useful utility class: ZipFile.

We already talked about it in a previous post: http://blog.codefluententities.com/2012/08/24/exploring-the-codefluent-runtime-zipfile/

The big advantage of this class is it uses an unmanaged implementation of the ZIP compression algorithm. It consumes less CPU and less memory. The implementation, written in C/C++, is located in a native DLL called CodeFluent.Runtime.Compression.dll. It’s provided in 32 and 64-bit version, and both versions have the same name.

If you use the commercial CodeFluent Entities product, this 32-bit version DLL is located in the %programfiles(x86)%\SoftFluent\CodeFluent\Modeler directory, and the 64-bit version DLL is located in the %programfiles(x86)%\SoftFluent\CodeFluent\x64 directory.

If you use the Nuget package, both versions are shipped each in a x86 or x64 directory in the package.

There are few problems with this:

  1. Since the CodeFluent.Runtime.Compression.dll is a native DLL, it must be available in the standard DLL search path. The standard way of shipping it was to copy the DLL aside the .NET .exe you were developing.
  2. The problem with this is you can’t write easily a .NET .exe built as “Any CPU” that uses the ZipFile class, because both versions of the DLL have the same name. So you have to build and ship two versions (32 and 64-bit) of your .NET exe just to overcome this, and you must install them in separate directories, even if the rest of your .EXE works just fine in “Any CPU” mode…

To solve these issues, starting with CodeFluent version 760, the new ZipFile class has changed the way it finds the CodeFluent.Runtime.Compression.dll dll. The algorithm is now the following:

CodeFluent ZipFile Compression

So, existing installations should not be affected by this, however our new recommendation is:

  • If you’re writing applications that will run on machine that have the CodeFluent Entities commercial product installed (build 760 or higher), then… do nothing. The ZipFile class will find what it needs automatically.
  • If you’re writing applications that will be deployed on production machines where nothing special is installed, then don’t ship CodeFluent.Runtime.Compression.dll aside your .exe anymore but rename it as CodeFluent.Runtime.Compression.x86.dll and CodeFluent.Runtime.Compression.x64.dll and ship both aside your .exe. If you specifically compile your .exe as X86 or X64, you can put only the one required. If it’s “Any CPU”, copy both.

Happy zippin’ !

The R&D team.


The new SQL Server Pivot Script producer

$
0
0

A new producer is available since the latest builds!

Enter the “SQL Server Pivot Script” producer.

This producer purpose is to allow you to deploy CodeFluent Entities-generated SQL Server databases on any machines (production servers, etc.) much easier.

Before that, during development phases, the CodeFluent Entities SQL Server producer was already able to automatically upgrade live SQL Server databases using an integrated component called the Diff Engine. We all love this cool feature that allows us to develop and generate continuously without losing the data already existing in the target database (unlike most other environments…).

Now, this new producer provides the same kind of feature, but at deployment time.

It generates a bunch of files that can be embedded in your setup package or deployed somewhere on the target server. These files can then be provided as input to a tool named the PivotRunner. This tool will do everything needed to upgrade the database to the required state. It can create the database if it does not exist, add tables, columns, view, procedures, and keys where needed, etc. It will also add instances if possible.

Here is some diagram that recaps all this:

SQL Server Pivot Script Producer

SQL Server Pivot Script Producer


To use it at development/modeling time:
  • Add the SQL Server Pivot Script producer to your project and set the Target Directory to a directory fully reserved for the outputs this tool will create. Don’t use an existing directory, create a new one for this.
  • Once you have built the project, this directory will contain at least one .XML file, but there may be more (if you have instances and blob instances for example). If you set ‘Build Package’ to ‘true’ in the producer’s configuration, the output will always be one unique file with a .parc (pivot archive) extension.
  • Copy these files where you want, or add them to your setup projects.

Now, at deployment time you have two choices:

1) Use the provided tool (don’t develop anything).

Use the CodeFluent.Runtime.Database.Client.exe (CLR2) or CodeFluent.Runtime.Database.Client4.exe (CLR 4) binaries. Just copy them to your target machine. You will also need CodeFluent.Runtime.dll and CodeFluent.Runtime.Database.dll. The tool is a simple command line tool that takes the pivot directory or package file as input.

2) Use the PivotRunner API.

The tool in 1) also uses this API. It’s a class provided in CodeFluent.Runtime.Database.dll (you will also need to reference the CodeFluent.Runtime.dll). The PivotRunner class is located in the CodeFluent.Runtime.Database.Management.SqlServer namespace.
This is very easy:

            PivotRunner runner = new PivotRunner(pivotPath);
            runner.ConnectionString = "This is my SQL Server connection string";
            runner.Run();

If you need to log what happens, just gives it an instance of a logger, a class that implements IServiceHost (in CodeFluent.Runtime), for example:

        public class PivotRunnerLogger : IServiceHost
        {
            public void Log(object value)
            {
                Console.WriteLine(value);
            }
        }

What happens in the database during diff processing can also be logged, like this:

            PivotRunner runner = new PivotRunner(pivotPath);
            runner.Logger = new PivotRunnerLogger();
            runner.ConnectionString = "This is my SQL Server connection string";
            runner.Run();
            runner.Database.StatementRan += (sender, e) =>
                {
                    Console.WriteLine(e.Statement.Command);
                };

Note: This producer is still in testing phase, the forums are here if you need help!

Happy diffin’

The R&D team.


CodeFluent Entities and Visual Studio 2013

$
0
0

Good news: Visual Studio 2013 is now available for download and CodeFluent Entities latest build (61214.761) runs great on it!

CFE-VS2013

You can learn the new features of Visual Studio 2013 here:

The Visual Studio 2013 download includes the .NET framework 4.5.1. If you have not seen it yet, you can read about the framework here:

On November 13th, do not miss the Visual Studio 2013 Virtual Launch.  You will discover the breadth and depth of new features and capabilities in the Visual Studio 2013 release.

Note that you can download the latest version of CodeFluent Entities here, or update your version using the Licensing tool.

Remember that you can follow the latest new features and bug fixes of CodeFluent Entities subscribing to this RSS.

Enjoy! :-)
Sabrina Pereira


[Pet Shop Reloaded] The End

$
0
0

 
Across this series of posts we have seen how is to design and build a business application using CodeFluent Entities and Entity Framework 5 and as you have seen, we can say that CodeFluent Entities can be located as a superset of Entity Framework (taking into account that CodeFluent Entities does not rely on Entity Framework).
 

Richer Modeler

 
As you could see, the CodeFluent Entities modeler is a very advanced one. The number of notions supported by CodeFluent Entities is larger than those of Entity Framework:
 

  • namespaces
  • model search engine
  • aspects and dynamic modeling
  • code snippets
  • methods
  • attributes
  • rules
  • rules editor
  • instances
  • forms
  • forms editor
  • configuration properties
  • model design customization
  • menu/action ribbon
  • inferred model
  • multi surface/file model
  • naming conventions
  • user defined types

 

Performance and readability

 
Entity Framework generate SQL code dynamically which can be ok when you have a small application and when you don’t need to debug/understand your SQL code. Indeed, dynamically generated code is not easy to read and can present performance issues when dealing with complex queries. All SQL code generated by CodeFluent Entities is generated in design time so you know in advance exactly the code that will be called.
 

linq-to-entities

linq-to-entities


 
Using CFQL

Using CFQL


 
The first image shows a query using Entity Framework and Linq-to-Entities, we can also see the dynamically SQL generated code translated from the C# code. The second image shows the same query using CodeFluent Entities and its language agnostic query system (CFQL), all this in design time.
 

Multipart model

 
When working with a large model or when several members of a team modify the same model it is really handy to split the model in different parts (files), this is not possible with Entity Framework without losing information and you may have experienced the consequences: merge conflicts, Visual Studio slows down…
 

No Mapping

 
When modeling your business domain with CodeFluent Entities you don’t need to make any specific mapping, you can easily add, remove and update elements in your model and CodeFluent Entities does the rest.
 

Continuous generation

 
CodeFluent Entities embraces the notion of Continuous Generation, it means that you can “tune” your model (update, go back) until it suits your needs and then generate it over and over again without losing any data, this is possible thanks to the CodeFluent Entities diff engine. This way you can more easily support functional changes.
 

Write less code

 
CodeFluent Entities will save you thousands of lines of code, code that the development team would have to write, code that would need to be tested and code that would always have a risk to have errors.  As all we know:
 
the less code we write…

  • the less that can go wrong
  • the sooner we’ll be done
  • the fewer bugs we write
  • the less we have to maintain
  • the better…

 

We haven’t seen everything

 
We have only covered a piece of the potential of CodeFluent, it provides a huge set of producers:

  • WPF
  • WindowsForms
  • Azure
  • Windows 8
  • ASP.NET MVC
  • WCF
  • REST/JSON web services
  • SharePoint
  • Silverlight proxy
  • advanced web services proxies
  • automatic traces
  • cache features
  • documentation files
  • Linq-to-Sql
  • Access and Excel lists
  • MS Build tasks
  • templates
  • web controls
  • and more…

That is explained by saying that CodeFluent Entities is not an ORM, it is a full model-driven software factory.
 

Code metrics

 
Let’s see a comparison of code metrics between the application built with CodeFluent Entities and Entity Framework.

We used the Visual Studio 2012 tool for code metrics analysis (Analyze -> Calculate Code Metrics for Solution).

We focalize on 3 indexes: Lines of Code, Maintainability Index and Cyclomatic Complexity. For each index the less is better.

Entity Framework – Code Metrics:
 

Entity Framework Code Metrics

Entity Framework Code Metrics


 
CodeFluent Entities – Code Metrics:
 
CodeFluent Entities Code Metrics

CodeFluent Entities Code Metrics


 
The code metrics analysis has not been applied to generated code, that’s why the “PetShopReloaded” project has a value of 0 Lines of Code for the CodeFluent Entities solution.

 

We needed to modify the t4 templates (Model.tt and Model.Context.tt) for Entity Framework in order to generate the System.CodeDom.Compiler.GeneratedCodeAttribute attribute so the generated code has not been taken in account by the code metrics tool. CodeFluent Entities generated that attribute by default.

 
As we can see we will need to maintain more code (and more complex) for the solution built with Entity Framework.
 

Finally

 
If you are convinced by all the advantages that CodeFluent Entities can provide to your software engineering process but you have already started with Entity Framework, don’t worry, CodeFluent Entities provides a “Entity Framework Importer” (http://www.softfluent.com/documentation/Importer_EntityFrameworkImporter.html) :)
 
Regards,
 
The SoftFluent team
 
 


Exploring the CodeFluent Runtime: The Template Engine

$
0
0

As you probably know, we released a few year ago the CodeFluent Runtime as a free Nuget Package named CodeFluentRuntimeClient. This is a set of utilities which is usable across all types of .NET applications (WPF, WinForms, ASP.NET, console, Windows service, etc.) and aims to ease the developer’s life.

Today, I’d like to introduce you, as part of the Exploring the CodeFluent Runtime series, an easy-to-use class to generate documents from a template source file.
You should ask yourself what is a template in term of software development. It’s simply a mixture of text blocks and control logic that can generate an output file. With our template engine, the control logic is written in JavaScript as fragments of program code. By default, the engine is based on the fast IE9+ “chakra” JavaScript engine developed by Microsoft for its Internet Explorer web browser.

Before we go any further it’s important to briefly describe the two following classes from the CodeFluent.Runtime.TemplateEngine namespace:

Template: Defines properties and characteristics of an ActiveX Scripting template and provides a set of methods to load and process a template file.

ParsedTemplate: In-memory and compiled representation of your template file (JavaScript).

The following diagram shows how the template engine internally works:

CodeFluentRuntimeClient Template

If you want to understand how to parse and execute JavaScript by C#, just have a look to this StackOverflow discussion. You’ll find how to interop with the JavaScript “IE9+ Chakra” JavaScript engine.

The easiest way to understand how to use the template engine is by way of an example. The first thing we have to do is create our template file.

Consider the following Rtf input file:

RTF Input file

Rtf Input file

The “<% %>” tag represents the JavaScript code blocks. Let’s use the Template engine in order to process the template described above:

// The ComVisible indicates that the managed type is visible to COM.
[ComVisible(true)]
public class OrderLine
{
    public string ProductName { get; set; }
    public decimal UnitPrice { get; set; }
    public int Quantity { get; set; }
}

class Program
{
    static void Main(string[] args)
    {
        // initialize the argument dictionary.
        IDictionary<string, object> arguments = new Dictionary<string, object>();
        arguments.Add("orderLine1", new OrderLine() { ProductName = "Product A", Quantity = 5, UnitPrice = 12 });
        arguments.Add("orderLine2", new OrderLine() { ProductName = "Product B", Quantity = 10, UnitPrice = 30 });
        arguments.Add("orderLine3", new OrderLine() { ProductName = "Product C", Quantity = 4, UnitPrice = 40 });

        CodeFluent.Runtime.TemplateEngine.Template template = new CodeFluent.Runtime.TemplateEngine.Template();

        // Load the source template with the argument intiliazed above.
        template.Load("PurchaseOrder_Template.rtf", arguments.Keys.ToArray());

        using (StreamWriter writer = new StreamWriter(@"PurchaseOrder.rtf"))
        {
            // Run the template using the CodeFluent Runtime Template engine.
            template.Run(writer, arguments);
        }
    }
}

For running this code you have just to reference the CodeFluent Runtime Client Library and when executing it you’ll get the generated output file :

Rtf Output file

Rtf Output file

It’s good to know that the template engine is fully extendable. It would be helpful if you want to add your own keywords or business rules. For this purpose, you should inherit from the Template and/or ParsedTemplate objects.

On the same topic and through the CodeFluent Entities product, we are shipping a Template producer which is an engine that allow developers to generate text files from template containing C# code blocks.

Happy templating,

Antoine Diekmann



Exploring the CodeFluent Runtime: The Ribbon Control

$
0
0

Hey, unless you lived on another planet the last 7 years, you guys should know what is a Ribbon is in terms of user interface. It’s a sophisticated set of toolbars and buttons placed on several tabs that allows you to quickly find the commands to complete a task. Since the release of Microsoft Office 2007 (Word, Excel, PowerPoint), this kind of control has become greatly appreciated by developers to provide a great user experience to their applications.

Office Ribbon

Office Ribbon

Now, the free CodeFluent Runtime Client Library that we, at SoftFluent, provide, will allow us to easily integrate a similar control in your Windows Forms applications. First of all, just take a look at the following screenshot of this RibbonControl schema:

RibbonControl01

The RibbonControl consists of different tabs called RibbonTab (crazy huh?). Each tab (as ‘Home’ and ‘View’ above) can include one or several groups of controls of RibbonPanel type (as ‘Clipboard’, ‘Font’, ‘Paragraph’, and ‘Insert’ above). Each panel consists of a list of RibbonItems objects (RibbonItem is not a control, it’s just a wrapper object). Each RibbonItem can embed standard controls such as a Button or a DropDownList.

Now, I’m going to explain how to create the RibbonControl introduced above programmatically (as of today, we don’t provide a cool Visual Studio designer integration, so this is in fact the only way to use this control…)

Add a RibbonControl in a Windows form (Winforms technology) :

The first easy step is to add a RibbonControl, in the same way that you would add a button to a form. The RibbonControl inherits from the Control class:

var ribbonControl1 = new CodeFluent.Runtime.Design.RibbonControl();

this.Controls.Add(ribbonControl1);

Add RibbonTabs to RibbonControl:

var homeTab = new CodeFluent.Runtime.Design.RibbonTab("Home");
var viewTab = new CodeFluent.Runtime.Design.RibbonTab("View");

ribbonControl1.Tabs.Add(homeTab);
ribbonControl1.Tabs.Add(viewTab);

Add RibbonPanel to RibbonTab:

var clipBoardPanel = new CodeFluent.Runtime.Design.RibbonPanel("Clipboard");
var fontPanel = new CodeFluent.Runtime.Design.RibbonPanel("Font");
var paragraphPanel = new CodeFluent.Runtime.Design.RibbonPanel("Paragraph");
var insertPanel = new CodeFluent.Runtime.Design.RibbonPanel("Insert");

homeTab.Panels.Add(clipBoardPanel);
homeTab.Panels.Add(fontPanel);
homeTab.Panels.Add(paragraphPanel);
homeTab.Panels.Add(insertPanel);

Here is the result:
RibbonControl03

Add RibbonItem to RibbonPanel:
Finally, we add some standard controls to the RibbonPanel :

var copyButton = new CodeFluent.Runtime.Design.RibbonButton("Copy");
copyButton.Mode = CodeFluent.Runtime.Design.RibbonItemMode.Icon;
copyButton.IconIndex = 0;

var pasteButton = new CodeFluent.Runtime.Design.RibbonButton("Paste");
pasteButton.Mode = CodeFluent.Runtime.Design.RibbonItemMode.Icon;

var pasteOptionDdl = new CodeFluent.Runtime.Design.RibbonDropDownList("Paste options");

pasteOptionDdl.Items.Add(new CodeFluent.Runtime.Design.RibbonDropDownItem("Paste"));
pasteOptionDdl.Items.Add(new CodeFluent.Runtime.Design.RibbonDropDownItem("Paste special"));
clipBoardPanel.Items.Add(copyButton);
clipBoardPanel.Items.Add(pasteButton);
clipBoardPanel.Items.Add(pasteOptionDdl);

Just compile your code to get the desired result :

RibbonControl03

RibbonControl provides an ImageList property that can’store all the icons we need (such as ‘Copy’ / ‘Paste’ buttons here). So, for example, we can add two images to our Windows Forms project and to the image collection (ImageList) of the RibbonControl:

ribbonControl1.ImageList = new ImageList();
ribbonControl1.ImageList.ImageSize = new System.Drawing.Size(32, 32);

ribbonControl1.ImageList.Images.Add(Image.FromFile(@"Images\copyButtonIcon.png"));
ribbonControl1.ImageList.Images.Add(Image.FromFile(@"Images\pasteButtonIcon.png"));

To assign one of these icons to RibbonItem, simply assign the RibbonItem’s IconIndex property, which corresponds to the index of an image in this list:

pasteButton.IconIndex = 1;

Note that you can also resize all images in the collection this way :

ribbonControl1.ImageList.ImageSize = new System.Drawing.Size(32, 32);

In order to handle different sizes of icons, the RibbonControl exposes a second image collection, the SmallImageList. To assign an icon of this collection, just use the SmallIconIndex property.

Convenient and easy, don’t you think ?

Add RibbonControl in WPF application

Since WPF day one, it’s possible to host Windows Forms controls in your WPF application. So, if you need to use the RibbonControl in xaml, check out this article.

There are expensive ribbon controls out on the market offering much more features than this one.  Its main advantage is it’s simple and … free. This control is provided 100% free of charge. Its license is tied to the CodeFluent Runtime Client license (which basically allows you to do anything with it…). The support is provided on a best-effort basis, so if you have any questions about this control or our products, feel free to visit the SoftFluent forum.

Happy ribboning!

The R&D team.


Exploring the CodeFluent Runtime: Country utilities

$
0
0

The CodeFluent.Runtime.Utilities.Country class is a cool tool that provides information about countries, regions, geographic locations and currencies.

Below is a figure showing a WPF application with a DataGrid that contains a list of countries with the information this class provides: locale identifier, region, english name, native name (in the corresponding language), currencies, etc.)

Country

XAML :

<Grid>
    <DataGrid x:Name="MyDataGrid" />
</Grid>

C# :

MyDataGrid.ItemsSource = CodeFluent.Runtime.Utilities.Country.AllCountries;

By running the code above, you’ll get a list of countries as a data source for your WPF DataGrid.

The Country object also exposes some useful methods such as:

GetCountry : find a country by its ISO-3166 two-letter code

CodeFluent.Runtime.Utilities.Country.GetCountry("AL")

It also supports principal subdivisions (e.g., provinces or states) of all countries coded in ISO 3166 so you can get locations and not only countries:

// *private joke* Carl, this one's for you !
var guadeloupe = CodeFluent.Runtime.Utilities.Country.GetCountry("GL");

// Get all locations installed on your system.
var allLocations = CodeFluent.Runtime.Utilities.Country.AllLocations;

GetCurrencyCountries : find countries for a given ISO currency symbol

var euroCountries = CodeFluent.Runtime.Utilities.Country.GetCurrencyCountries("EUR")

So here is the same grid with the list of countries that use EURO currency:

Country

Before leaving this topic, I suggest you have also have a look at the CultureComboBox control available in the CodeFluent.Runtime.Design namespace. It provides an associated Winforms ComboBox specialized for displaying countries.

The CodeFluent Runtime is  available with the full CodeFluent Entities product and with the CodeFluent Runtime Client 100% free assembly (available directly from Nuget).

Happy countrying!

The R&D team.


Exploring the CodeFluent Runtime: Web Controls – Part 1

$
0
0

Today, on the series “Exploring the CodeFluent Runtime” we’re going to explore the ASP.Net Web Controls inside the CodeFluent.Runtime.Web namespace. This is all provided as part of CodeFluent Entities.

In the CodeFluent.Runtime.Web assembly, you’ll find several controls usable in ASP.Net WebForms applications. The first we’ll see are controls used to render UI relatively to the data (bindings).

BooleanControl (CodeFluent.Runtime.Web.UI.WebControls.BooleanControl) displays what’s defined in FalseTemplate or TrueTemplate according to a boolean value.

<cfe:BooleanControl ID="BooleanControl1" runat='server' Value='<%# Eval("MyBooleanValue") %>' AutoBind="true">
    <TrueTemplate>
        This template will be displayed if Value is evaluated as "true"
    </TrueTemplate>
    <FalseTemplate>
        This template will be displayed if Value is evaluated as "false"
    </FalseTemplate>
</cfe:BooleanControl>

CompareControl (CodeFluent.Runtime.Web.UI.WebControls.CompareControl) displays FalseTemplate or TrueTemplate according to what’s defined by the ValueToCompare attribute and an Operator (Equal, NotEqual,
GreaterThan, GreaterThanEqual, LessThan, LessThanEqual, DataTypeCheck). For the DataTypeCheck operator, the ValueToCompare will be the full name of the type to check.

<cfe:CompareControl ID="CompareControl1" runat='server' Value='<%# Eval("MyValueToCompare") %>' Operator="GreaterThan" ValueToCompare="0">
    <TrueTemplate>
        Value is greater than 0
    </TrueTemplate>
    <FalseTemplate>
        Value is less than or equal to 0
    </FalseTemplate>
</cfe:CompareControl>
 
<cfe:CompareControl ID="CompareControl2" runat='server' Value='<%# Eval("MyValueToCompare") %>' Operator="DataTypeCheck" ValueToCompare="System.Int32">
    <TrueTemplate>
        Value is a System.Int32
    </TrueTemplate>
    <FalseTemplate>
        Value is not a System.Int32
    </FalseTemplate>
</cfe:CompareControl>

MultiCompareControl (CodeFluent.Runtime.Web.UI.WebControls.MultiCompareControl) is similar to the CompareControl but is more like a switch.

<cfe:MultiCompareControl ID="MultiCompareControl1" runat="server" Value='<%#Eval("MyValueToMultiCompare") %>'>               
    <case ValueToCompare="10" Operator="GreaterThan">
            Value is greater than 10
    </case>
    <case ValueToCompare="0">
    Value is equal to 0
    </case>
    <default>
    Value is not equal to 0 and is less than or equal to 10
    </default>
</cfe:MultiCompareControl>

ExistsControl (CodeFluent.Runtime.Web.UI.WebControls.ExistsControl) displays FalseTemplate or TrueTemplate depending on a given value. The value is tested against “null”, “DBNull”, or an empty string (possibly trimmed).

<cfe:ExistsControl ID="ExistsControl1" runat='server' Value='<%# Eval("Email") %>' Trim="true">
    <TrueTemplate>
        This template is displayed only if Value is not null or empty 
    </TrueTemplate>
    <FalseTemplate>
        This template is displayed when Value is null
    </FalseTemplate>
</cfe:ExistsControl>

When you work with enumerations into your Model, you want to be able to display and edit them easily into your forms or GridView. We have a solution for you! Let me introduce the Enum Controls.

EnumCheckBoxList (CodeFluent.Runtime.Web.UI.WebControls.EnumCheckBoxList) derives from the standard CheckBoxList control but is automatically filled with the fields of the enumeration type you define EnumTypeName parameter. Note this also supports multi-valued enumerations (with a [Flags] custom attribute).

EnumRadioButtonList (CodeFluent.Runtime.Web.UI.WebControls.EnumRadioButtonList) derives from the standard RadioButtonList control. As the EnumCheckBox, you only need to define the EnumTypeName attribute

EnumDropDownList (CodeFluent.Runtime.Web.UI.WebControls.EnumDropDownList) derives from the standard DropDownList and works the same way.

Another control that allows you to quickly bind your data is the BoolControl (CodeFluent.Runtime.Web.UI.WebControls.BoolControl). The BoolControl is a visual custom control that displays a System.Boolean or Nullable<System.Boolean> bound value. Depending whether the value is nullable or not, it can display a True/False or True/False/Undefined visual. It can use a CheckBox, DropDownList, horizontal button list, ListBox or horizontal or vertical radio button list to display these 2 or 3 items. It also supports read-only rendering and custom texts, interesting for localization purposes.

Is Customer:

<cfe:BoolControl ID="BoolControl1" runat="server" Value='<%# Bind("IsCustomer") %>' TrueText="Yes" FalseText="No" UnspecifiedText="Undefined" BoolControlType="HorizontalRadioButtonList" />

Contact Method:

<cfe:EnumCheckBoxList ID="EnumCheckBoxList1" runat="server" Value='<%# Bind("MethodToContact") %>' EnumTypeName="BlogCFE.ContactManager.ContactMethod" />
Origin (RadioButton):
<cfe:EnumRadioButtonList ID="EnumRadioButtonList1" runat="server" Value='<%# Bind("Origin") %>' EnumTypeName="BlogCFE.ContactManager.ContactOrigin" />
Origin (DropDown):
<cfe:EnumDropDownList ID="EnumDropDownList1" runat="server" Value='<%# Bind("Origin") %>' EnumTypeName="BlogCFE.ContactManager.ContactOrigin" />           

Here is the result:

For each of these controls, an associated DataControlField exists so you can use them in GridView, DetailsView, etc.

<cfe:BoolField DataField="IsCustomer" HeaderText="Is Customer" TrueText="Yes" FalseText="No" BoolControlType="DropDownList" />
<cfe:EnumCheckBoxListField DataValueField="MethodToContact" HeaderText="Contact method" EnumTypeName="BlogCFE.ContactManager.ContactMethod" />
<cfe:EnumRadioButtonListField DataValueField="Origin" HeaderText="Origin (RadioButton)" EnumTypeName="BlogCFE.ContactManager.ContactOrigin" />
<cfe:EnumDropDownListField DataValueField="Origin" HeaderText="Origin (DropDown)" EnumTypeName="BlogCFE.ContactManager.ContactOrigin" />        

the result in a grid view:

List of Contacts

As you’ve seen, these controls can avoid you to write a lot of code focusing more on a declarative way of programming.

In the next article, we’ll introduce the DataSources controls and another couple of cool utilities.

The R&D team.


Multi-database architecture with CodeFluent Entities

$
0
0

In this article, we’ll see how to use multiple stores in your CodeFluent Entities application. In a previous post, we explained that the Modeler doesn’t provide a “Store Name” property in the producer’s configuration property grid. It’s now fully supported in the product so you don’t need to modify your XML parts by hand.

However, before we go any further, let’s bring some theory. The CodeFluent Entities “store” concept can be seen as a virtual storage unit and is mainly used by the persistence layer producers. Your CodeFluent Entities model contains by default one store which is always visible in your model, in the Visual Studio’s solution explorer tree view:

If you need to add a new Store, right-click on the “Stores” node and select “Add new Store”. Simply choose a name and your application now contains two stores: CarRental and CarRentalReferential.

Okay, great… but why would I want to do this?

When you develop an application, you may feel the need to dispatch your tables (inferred from model entities) in more than one database. For example, I want to create the Customer table in the CRM Database, and the Product table in the Master Data Database. Well, this is exactly why the store concept exists. Another example is shown here in this diagram:

Multidatabase Architecture with CodeFluent Entities

Now, how to configure the “City”, “Address” and “Country” entities so their inferred tables will be generated to the CarRental database? It’s very easy : just select each of them, open the Properties window (F4), select the property grid Advanced tab (pointed by the red arrow below), and specify the target store like this:

Then you can define two persistence producers in your project and assign each of them a specific store:

Now don’t forget to configure your store and set it a specific connectionString. By building your model, CodeFluent Entities will generate the code corresponding to each store. The right things in the right places ;) !

Store SQL result

To conclude, I’d to like to point out that, by design and by default, you can’t create model-level relationships between entities from different stores. Databases could be located in different servers or in different storage systems. But if you know what you’re doing, and still need this, you can change this default behavior by setting the allowCrossStoreRelations attribute on your project.

Happy Storing!

Antoine Diekmann


Exploring the CodeFluent Runtime: Web Controls – Part 2

$
0
0

In Part 1 of this series, we looked at some useful controls from the CodeFluent.Runtime.Web assembly.
On the same subject, we’ll explore in this post some other very useful controls for ASP.NET WebForms application.

The first controls are DataSource controls; They aren’t visual but very convenient as they can be bound to any DataBound controls like GridView, ListView, etc.

CountryDataSource (CodeFluent.Runtime.Web.UI.CountryDataSource) gives you a list of countries with a lot of properties, including localization information (EnglishName, NativeName, Location, Region, etc.). The type of the enumerated item is CodeFluent.Runtime.Utilities.Country. You can learn more about this type in the related article on our blog.

<cfe:CountryDataSource ID="CountryDataSource1" runat="server"/>
<asp:GridView ID="GridView2" runat="server" DataSourceID="CountryDataSource1" AllowPaging="true">

CountryDataSource

CultureDataSource (CodeFluent.Runtime.Web.UI.CultureDataSource) gives you a list of CultureInfo (System.Globalization.CultureInfo) and can be bound with any DataBoundControl (GridView, DropDownList…).

<cfe:CultureDataSource ID="CultureDataSource1" runat="server" />
<asp:GridView ID="GridView3" runat="server" DataSourceID="CultureDataSource1" AllowPaging="true">

CultureDataSource

CodeFluent Entities comes with another cool Web Control: the CultureDropDownList.

CultureDropDownList (CodeFluent.Runtime.Web.UI.WebControls.CultureDropDownList) displays automatically for you a DropDownList filled with cultures. With a single line of code, you can let the user change the UI Culture of your website.
First, add this control to your page:

<cfe:CultureDropDownList id="cultures" runat="server" CultureCookieName="culture" AutoPostBack="true" TitleMemberName="EnglishIEStyle" TextMemberName="NativeName" CultureList="en-us;fr-fr" />

The CultureList property lets you set the cultures you want to display. By default, all available cultures (on the current computer) are loaded.

Then, just add the following code in the Global.asax file.

protected void Application_AcquireRequestState(object sender, EventArgs e)
{
    CultureDropDownList.SetRequestCulture(Request, "culture"); 
}

The second parameter corresponds to the name of the cookie set in the CultureDropDownList in the page.

Because the CultureDropDownList control is set to AutoPostBack=”true”, when the user selects another culture, the website page will automatically reload with the selected culture. Of course, you need to put in place the ASP.NET globalization mechanism and provide the corresponding resources files :).

FreeForm Control
Now, another topic. Let’s imagine you have several forms to implement as pages on your site, most of them used to get simple input from your users. Let’s suppose you want to send email with the content of the forms. This can be useful for polls for example.

For this, you can use the FreeForm control (CodeFluent.Runtime.Web.UI.WebControls.FreeForm). It allows you to create an arbitrary form, add all the child controls you want to it and then add a piece of code to gather all the user input data. Here is a quick example.

We start with a simple markup:

<cfe:FreeForm ID="FF" runat="server" OnFormChanged="OnFormChanged" DecamelizeOptions="Default" >
    <ItemTemplate>
        <asp:Panel ID="Panel3" runat="server" GroupingText="Personnal Information">
            <asp:Label ID="Label1" runat="server" Text="Preferred Name:" /><br />
            <asp:TextBox ID="TextBox1" runat="server" Text='<%#Bind("PreferredName") %>' /><br />
            <asp:Label ID="Label2" runat="server" Text="City:" /><br />
            <asp:TextBox ID="TextBox3" runat="server" Text='<%#Bind("City") %>' /><br />
        </asp:Panel>
        <asp:Panel ID="Panel4" runat="server" GroupingText="Business Information">
            <asp:Label ID="Label3" runat="server" Text="Your Company:" /><br />
            <asp:TextBox ID="TextBox4" runat="server" Text='<%#Bind("YourCompany") %>' /><br />
            <asp:Label ID="Label4" runat="server" Text="Describe your primary role and function:" /><br />
            <asp:TextBox ID="TextBox5" runat="server" Text='<%#Bind("DescribeYourPrimaryRole_x0026_Function") %>' /><br />
        </asp:Panel>
        <br />
        <asp:Button ID="Button2" runat="server" Text="OK" />
    </ItemTemplate>
</cfe:FreeForm>

We have a form with 4 textboxes and their corresponding labels into 2 panels, plus a standard button to submit :

When the user submits the button, the whole input data will be transformed into a dictionary instance automatically. Each control will provide a dictionary entry in that instance. Notice that all the Text attributes of the textboxes have a standard ASP.NET bind token attached. That token will become the entry field key, and the entry value will be the data entered by the user (whatever the type of this data and the type of the control). To get this dictionary you just need to attach to the FormChanged event and read the Values property of the FormChangedEventArgs parameter, like this:

<script runat="server">
    protected void OnFormChanged(object sender, FormChangedEventArgs e)
    {
        StringBuilder sb = new StringBuilder();

        foreach (DictionaryEntry de in e.Values)
        {
            sb.AppendLine(de.Key + "=" + de.Value + "<br/>");
        }
        
        // NOTE: instead, send email here with the content of the StringBuilder
        litResult.Text = sb.ToString();
    }
</script>     

You may have noticed that we have defined the field names using camel-case and also some weird hexadecimal notation. The FreeForm control has the ability to “decamelize” these keys and unescape the Unicode characters represented by their hexadecimal values. This trick allows us to use anything for key names (although the Bind syntax is much more restrictive). You can define several options in the DecamelizeOption attribute (None, ForceFirstUpper, ForceRestLower, UnescapeUnicode, UnescapeHexadecimal, ReplaceSpacesByUnderscore, ReplaceSpacesByMinus, ReplaceSpacesByDot, KeepFirstUnderscores, DontDecamelizeNumbers, KeepFormattingIndices).

So, this simple example gives you the following result:

Of course, you will hopefully implement something more useful in your project :) You can also imagine having a form generator for power-users, letting them design simple forms and process the Key/Value Dictionary generated by the FreeForm control in a pretty much automatic way.

NumericTextBox Control
Do you need a numeric-only textbox input?. CodeFluent.Runtime.Web has a solution for you: the NumericTextBox control.

The NumericTextBox control (CodeFluent.Runtime.Web.UI.WebControls.NumericTextBox) prevents user from entering non-numeric characters. You can define the value type with the TargetTypeName attribute, define the MaximumNumbers, MaximumIntegerNumbers, MaximumDecimalNumbers or the Negative or Positive Sign. Note this control can be used inside a FreeForm control we say previously.

<cfe:NumericTextBox ID="NumericTextBox1" runat="server" Value='<%# Bind("NumberOfEmployees") %>' TargetTypeName="System.Int32" />

There is also associated DataControlField, NumericTextField CodeFluent.Runtime.Web.UI.WebControls.NumericTextField) fields controls that you can use in GridView, DetailsView, etc.

<cfe:NumericTextField DataField="Age" HeaderText="Age" TargetTypeName="System.Int32"/>

Captcha Control
The Captcha control (CodeFluent.Runtime.Web.UI.WebControls.CaptchaControl) displays an image with some simple text inside, but supposedly quite difficult to read for machines. You can define the image size, the complexity of the produced image, and a timeout duration. Notice that the image is generated by the BinaryLargeObjectHttpHandler of CodeFluent Entities (Learn more about Blob here).

The Captcha control comes with its validator, the CaptchaValidator control (CodeFluent.Runtime.Web.UI.WebControls.CaptchaValidator). As any validator, you just need to declare the ControlToValidate and the CaptchaControlID associated.

In this example, we just display a message if the text entered corresponds to what was generated by the Captcha control.

<cfe:CaptchaControl ID="CaptchaControl1" runat="server" Width="200px" Height="50px" Expiration="120"
    Options="FontWarpFactorMedium, BackgroundNoiseLevelHigh,LineNoiseLevelHigh" />
<br />
Please enter the code or press F5 to refresh the browser
<br />
<cfe:CaptchaValidator ID="CaptchaValidator1" runat="server" ControlToValidate="Verify" CaptchaControlID="CaptchaControl1"
    SetFocusOnError="True" ErrorMessage="The code doesn’t match or there was a timeout" ForeColor="Red" />
<br />
<asp:TextBox ID="Verify" runat="server" EnableViewState="False" AutoCompleteType="None" />
<asp:Button ID="btValidate" runat="server" Text="Validate" OnClick="btValidate_Click" /><br />
<asp:Label ID="lblResult" runat="server" Text="You enter the correct text! Thank you for validating." Visible="false" ForeColor="Green"/>

In the button Click event, call Page.IsValid to validate the captcha:

<script runat="server">
    protected void btValidate_Click(object sender, EventArgs e)
    {
        if (Page.IsValid)
        {
            lblResult.Visible = true;
        }
        else
        {
            lblResult.Visible = false;
        }
    }
</script> 

Have a look at the Captcha image here:

Captcha

As you’ve seen in this serie, CodeFluent.Runtime.Web can be very useful to us, web developers who are tired to write a lot of code-behind to do simple actions. With these controls you just need to drag and drop them on your page, save and enjoy.

These controls are located in the CodeFluent.Runtime.Web assembly, part of the CodeFluent Entities product ! Try them!

Happy controling!

The R&D team.


Multi-database deployment with PowerShell and the Pivot Script Runner – Part 1

$
0
0

We are working on a solution designed with CodeFluent Entities, which stores and manages data within a SQL Server database created by the SQL Server Producer.
Sometime in the past, we deployed this solution on many servers and, now, we want to keep them all up to date.
Recently, we have made some important changes and we want to deploy them on our many databases.

How to set up and automate the process of updating a range of databases while preserving their content?

Pivot Script Producer

To answer this question, we have developed a new producer called “The Pivot Script Producer”. It provides the opportunity for generating one or more XML files which are a database snapshot of the current CodeFluent Entities project model.

Pivot Runner

These files, generated by the pivot script producer, are intended to be consumed by the PivotRunner tool of the CodeFluent.Runtime.Database library.
Using a connection string, it updates the targeted database from the files we have previously sent to him.

The New SQL Server Pivot Script producer article shows that we can directly use the PivotRunner API from the library. But, even easier, we can just call one of the provided programs: CodeFluent.Runtime.Database.Client.exe or CodeFluent.Runtime.Database.Client4.exe, located in the CodeFluent Entities installation folder.

At this stage, we can very easily and quickly update one database. But we still want to apply this process on several databases!

PowerShell Script

Let’s use the PowerShell strengths ! :)

Powershell is a scripting language developed by Microsoft and default running on any Windows system since Windows Seven. With a fully object-oriented logic and a very close relationship with the .NET Framework, it has become an essential and very simple and useful tool. And that’s why Powershell is so cool!

Thus, we could easily imagine a script that takes a list of servers as first parameter, and the generated files path as the second one to select and update the targeted databases (here, only the online databases whose name starts with “PivotTest_”).

param([string[]]$Hosts, [string]$PivotFilePath)

if ($Hosts -eq $null -or [string]::IsNullOrWhiteSpace($PivotFilePath))
{
    Write-Error "Syntax: .\UpdateDatabases.ps1 -Hosts Host1[, Host2, ...] -PivotFilePath PivotFilePath"
    break
}

[System.Reflection.Assembly]::LoadWithPartialName('Microsoft.SqlServer.SMO') | out-null

Write-Host "-========- Script started -========-"

$Hosts | foreach {
    $srv = new-object ('Microsoft.SqlServer.Management.Smo.Server') $_

    $online_databases = $srv.Databases | where { $_.Status -eq 1 -and $_.Name.StartsWith("PivotTest_") }
    
    if ($online_databases.Count -eq 0)
    {
        Write-Error "No database found"
        break
    }

    Write-Host "Database list:"
    $online_databases | foreach { Write-Host $_.Name }

    [string]$baseConnectionString = "$($srv.ConnectionContext.ConnectionString);database="
    $online_databases | foreach {
        & “CodeFluent.Runtime.Database.Client.exe” “runpivot” $PivotFilePath "$($baseConnectionString)$($_.Name)"
}
}

Write-Host "-========-  Script ended  -========-"

The script above shows us how easily some .NET Framework features can be used. In particular the Microsoft.SqlServer.Management.Smo namespace that provides an intuitive way of SQL Server instances manipulation.

We could just call one of the CodeFluent Runtime Database programs described above, but the idea of using directly the PivotRunner through a custom PowerShell command is much more attractive!

Indeed, Powershell gives us that opportunity. These customs commands are called “Cmdlets” and can be built under C#.NET, as we will see later in the second part of this article :)

Happy deploying

The R&D team.


Generate your application with CodeFluent Entities and Syncfusion – Part 1

$
0
0

Building an application from scratch, including business logic layer, data access layer and an amazing user interface design is a difficult ordeal. In most of cases it also means a long development process.

CodeFluent Entities allows you to generate components such as scripts, code, web services and UIs. 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 that can be combined to obtain your own application following your desired architecture, using your desired technologies.

An application generated by CodeFluent Entities uses standard components of .NET Framework. Today, we want to let you know that you use the power of Syncfusion to build your application. This set of components makes it easy to build attractive applications with incredible design.

CodeFluent Entities Syncfusion

We’ll show you how to create the application from scratch. It includes multiple user interfaces such as an ASP.NET Back Office to manage your data and a great WPF client application using Syncfusion WPF components.

CodeFluent Entities and Visual Studio makes it extremely easy to create a project with a sample model. In the Add New Project dialog box select the ContactManager Sample Model template:

Add a new ContactManager sample Model

You also need two additional projects:

  • A Class Library named ContactManager which represents the Business Object Model (BOM in the CodeFluent Entities language). Just add a Persistence empty directory.
  • An ASP.NET Empty Web Application named ContactManager.WebApplication which represents the ASP.NET Back Office :

Once projects created, let’s take a look at the ContactManager model supplied by CodeFluent Entities :

Contact Manager Model

Now that you’ve created the model, you need a way to generate database scripts, Back Office web application and the business objects using CodeFluent Entities producers.

Producers

What is a producer?

A producer uses information available from the model to generate code. CodeFluent Entities provides more than 20 producers that allow to generate the database (SQL Server, Azure, Oracle, PostgreSQL and MySQL), the Business Object Model (C# or VB.NET), web services as well as user interfaces such as a web site.

Configuring the producers

We need to use the Business Object Model (BOM) producer to generate the object-oriented layer:

  • From the project ContactManager.Model, select Add New Producer.
  • Select the Business Object Model (BOM) producer
  • Configure the Target Project : ContactManager

Then you need to configure the « SQL Server » producer in order to generate database scripts (tables, views, stored procedures, etc.). From the project ContactManager.Model, select Add New Producer:

  • Select the SQL Server producer from Persistence Layer Producers
  • Target the Persistence directory from your ContactManager project
  • Configure the Target version attribute and select the version according to your SQL Server database.
  • Define the Connection String attribute

Finally we will add an « ASP.NET Web Site » producer to generate the user interface of the website. From the ContactManager.Model project, click « Add New Producer » :

  • Select the ASP.NET Web Site V2 from Web Producers.
  • Select the technology of your site by changing a Template Category
  • Target the directory of our ASP.NET project: ContactManager.WebApplication

The application is now ready to be generated. In a single click (or press F5) just build the solution to generate your application.
Before compiling the solution, don’t forget to add a reference to the « ContactManager » project to your « ContactManager.WebApplication » project references.

Below you will find some screenshots of the generated application. No handwriting code and a full ready-to-use Back Office web application :) .

The generated homepage by default lists all namespaces and their contained entities:

The generated home page

The generated home page

Clicking on an entity gets you to the entity page.

On the left side of the page you’ll find a list of actions available on this entity. Those actions correspond to business methods provided by the entity.

Contact list

Contact list

The generated website also supports CRUD operations to create, edit and delete your data.

You’ve now created a simple Back Office ASP.NET application that uses all the generated layers. In the second part, let’s develop a WPF application with Syncfusion components that uses WCF web services.

Download the zipped source code here.

Happy coding

The R&D team.



Generate your application with CodeFluent Entities and Syncfusion – Part 2

$
0
0

In Part 1 of this serie, we looked at building an ASP.NET Back Office Application with CodeFluent Entities.
Now, we would like to generate a WPF application using Syncfusion components that consumes the same datas.

There is nothing complicated here thanks to CodeFluent Entities.

We will describe the different steps to create a fully generated WPF application starting from a CodeFluent Entities custom template.

Create a custom producer

Using a custom producer, we will generate a “sexier” interface than the ASP.NET one as we’ve built before. This producer is based on a custom template and it uses Syncfusion’s components.

With a few simple steps the custom producer can be created:

  • Add a new Class Library project to your solution : ContactManager.SyncfusionProducer
  • Then, add the following references to the project : CodeFluent.Runtime, CodeFluent.Producers.UI, CodeFluent.Model, CodeFluent.Model.Common, CodeFluent.Producers.CodeDom
  • Create the WPFSyncfusionProducer class that inherits from the CodeFluent.Producers.UI.UIProducer

First of all, you simply need to override the two following properties

protected override string DefaultCategoryPath
{
    get
    {
        return ("SyncfusionWPF");
    }
}

protected override string NamespaceUri
{
    get
    {
        return "http://www.example.com/codefluent/producers.syncfusion/2011/1";
    }
}

Finally, you should not forget to override the Produce method to include your generation logic:

public override void Produce()
{
    base.Produce();

    Dictionary<string, string> context = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);

    ... // (check the attached source code for more details

    foreach (string sourceDirectory in this.GetFullSourceDirectories(this.CategoryPath, false))
    {
        BaseProducer.TransformAllFiles(this, this.FullTargetDirectory, sourceDirectory, context, new BaseProducer.TransformCallback(this.TransformFile));
    }
}

The dictionary will help us to reuse some properties directly inside your templates files.

We also shipped a compiled version of this producer directly in the attached solution. Just read the Readme text file before opening the solution. Note if you try to compile the project before copying the custom producer, you’ll get compiler errors.

How to deploy a custom producer?

Once your Syncfusion producer compiled, you should ask yourself how to use it. There is nothing complicated there. Create a Custom.config file in the %appdata%\CodeFluent.Modeler.Design directory with the following content:

<codeFluent.Modeler>
   <producerDescriptors>
     <producerDescriptor  name="SyncfusionWPF" 
                          displayName="Syncfusion WPF" 
                          category="Syncfusion Producers"
                          typeName="ContactManager.SyncfusionProducer.WPFSyncfusionProducer, ContactManager.SyncfusionProducer" />
   </producerDescriptors>
</codeFluent.Modeler> 

Then copy and paste the compiled producer « ContactManager.SyncfusionProducer.dll » into the CodeFluent Entities installation directory: C:\Program Files (x86)\SoftFluent\CodeFluent\Modeler.

Then, add a new producer with the following configuration:

Add new producer

What is a CodeFluent Entities Template ?

CodeFluent Entities provides a template engine which allows you to generate configuration files, documentation, extra sources, or any text files you might need. A template is simply a mixture of text blocks and control logic that can generate an output file

This is what it looks like:

Transform and Copy

The producer previously created will consume the template files to generate the final application. Obviously it includes some WPF Syncfusion components to improve the user experience.

Create your custom Template

The Syncfusion WPF template is available at the end, nevertheless the most interesting parts are described thereafter.

Here’s a quick code snippet to generate a file by entity:

[%@ template
enumerable="Producer.Project.Entities"
enumerableItemName="entity"
enumerableTargetPathFunc='Path.Combine(Path.GetDirectoryName(TargetPath), entity.Name) + "View.xaml"'
inherits="CodeFluent.Producers.UI.BaseTemplate" %]

This instruction means that we are going to iterate through all the entities in our project. The name of the generated file will be “[EntityName]View.xaml” and depends of the entity name.

Inside the user control template source file, we are going to use the Syncfusion Grid component and iterate through all properties of entity to generate the right visible columns types:

<syncfusion:GridDataControl x:Name="GridFusion"
                                        AllowEdit="False"
                                        AutoPopulateColumns="False"
                                        AutoPopulateRelations="False"
                                        ColumnSizer="Star"
                                        IsSynchronizedWithCurrentItem="True"
                                        NotifyPropertyChanges="True"
                                        ShowAddNewRow="False"
                                        ShowGroupDropArea="True"
                                        UpdateMode="PropertyChanged"
					                    PersistGroupsExpandState="True"
                                        VisualStyle="Metro"
                                        Grid.Row="1">

            <syncfusion:GridDataControl.VisibleColumns>

				[% foreach (ViewProperty vProp in entity.DefaultView.Properties) {
					if (vProp.UIEnabled)
					{						
Write(vProp, null, RendererTemplateSearchModes.None, RendererType.Read);
					}
				}%]

            </syncfusion:GridDataControl.VisibleColumns>
        </syncfusion:GridDataControl>

You’ll find the documentation for the CodeFluent Entities template engine by following this link.

Generate your application

Once your WPF application source code is generated, simply add Syncfusion references to your project and build it to get the following result:

Contact Manager Tiles View

Contact Manager Tiles View

Contact Manager Contact list

Contact Manager Contact list

By combining the CodeFluent Templating capabilities and the power of Syncfusion’s components together, you get a good mixture to generate functional and amazing applications. :)

But what happens if we modify the model (add/update/remove entities, properties, rules, etc.)? Just rebuild your project and it updates automatically your applications, your database and your Business objects Layer.

Using CodeFluent Entities, you define your business models in a centralized place; choose target platforms or technologies (including, but not limited to, data access), generate, and do it again continuously, as much as needed, without losing existing data.

Please leave feedback on how you liked this article and what we could improve. You can also find additional resources about Syncfusion here.

Download the zipped source code here.

Happy coding !

The R&D team.


The CodeFluent Entities Quiz

$
0
0

he CodeFluent Entities Quiz

CodeFluent Entities allows developers to generate rock-solid foundations for .NET applications from Visual Studio.

Do you want to win a CodeFluent Entities ultimate licence?

This full-featured edition is for commercial use and it includes advanced generators such as Oracle Database, SharePoint or Office, as well as official “out of the box” aspects (e.g. data localization and middle of word text search). To know more about the CodeFluent Entities editions, please visit our official store.

Participate by answering the quiz on our Facebook page from February 17th, 2014 to February 24th 2014. Click here to play!

4 days left to win ! Good luck ! :)

The SoftFluent team.


ASP.NET Identity and CodeFluent Entities

$
0
0

The ASP.NET Identity system is designed to replace the previous ASP.NET Membership and Simple Membership systems. It includes profile support, OAuth integration, works with OWIN and is included with the ASP.NET templates shipped with Visual Studio 2013.

ASP.NET Role and Membership providers are out of the box features provided by CodeFluent Entities. Today we’ll see how to create an ASP.NET Identity implementation with CodeFluent Entities.

Let’s do this ! :)

What do we have to do?

ASP.NET Identity provides a bunch of interfaces to define Users, Profiles, Logins, Roles, and how to store them.

A user is defined by the Microsoft.AspNet.Identity.IUser interface and a role is defined by the Microsoft.AspNet.Identity.IRole interface. Those interface are very generics:

public interface IUser
{
    string Id { get; }
    string UserName { get; set; }
}

public interface IRole
{
    string Id { get; }
    string Name { get; set; }
}

ASP.NET Identity also introduce the concept of user store to persist user information. There are different levels of functionalities depending of your needs:

Finally, the Microsoft.AspNet.Identity.UserManager is a higher level API that will coordinate different components such as the UserStore, the Password hasher and the user and password validation in order to manage users in your application.

Now you should have understood that to do our custom ASP.NET Identity we’ll implement the IUser, IRole and IUser*Store interfaces (yes all of them).

Let’s create the model


ASP.NET Identity - Model

User must implement the IUser interface. This can be done by adding an implementation Rule. The same apply for Role with the IRole interface.

To ensure the uniqueness of the username and role name we declared them at CollectionKey. This will also add automatically the methods User.LoadByUserName and Role.LoadByName.

To implement the UserStore we’ll need two more methods. The first one is to find a customer by a provider key. To do so we add a CFQL method on the user entity:

LOADONE(string providerKey) WHERE ExternalLogins.ProviderKey = @providerKey

We also need to delete a claim by User, Type and Value. This can also be done by CFQL

DELETE(User, Type, Value) WHERE User = @User AND Type = @Type AND Value = @Value

Those methods will be translated into stored procedures during the build process. Note that with CFQL you don’t have to bother with JOIN nor types ! :)

Below is a part of UserStore and RoleStore implementation :

public class UserStore :
    IUserStore<User>,
    IUserPasswordStore<User>,
    IUserSecurityStampStore<User>,
    IUserRoleStore<User>,
    IUserLoginStore<User>,
    IUserClaimStore<User>
{

    public Task CreateAsync(User user)
    {
        if (user == null) throw new ArgumentNullException("user");
        return Task.Run(() => user.Save());
    }

    public Task DeleteAsync(User user)
    {
        if (user == null) throw new ArgumentNullException("user");
        return Task.Run(() => user.Delete());
    }

    public Task<User> FindByIdAsync(string userId)
    {
        return Task.Run(() => User.LoadByEntityKey(userId));
    }
// ...
}

public class RoleStore : IRoleStore<Role>
{
    public Task CreateAsync(Role role)
    {
        return Task.Run(() => role.Save());
    }

    public Task<Role> FindByNameAsync(string roleName)
    {
        return Task.Run(() => Role.LoadByName(roleName));
    }
// ... 
}

Now we can use the UserStore through the UserManager and the RoleStore through the RoleManager:

new UserManager<User>(new UserStore())
new RoleManager<Role>(new RoleStore())

In the article we show that the code generated by CodeFluent Entities can easily be used with really new Framework like ASP.NET Identity. This is possible as CodeFluent Entities generates rock-solid foundation on which you can build your application !

The full implementation is available for download.

Happy user storing,

The R&D team.


And the winner is…

$
0
0

In a previous post, we talked about the The CodeFluent Entities Quiz and we asked three questions about basic features.

More than 60% of particpants answered 3 questions correctly. It wasn’t that difficult. :)

Quiz CodeFluent Entities

Here are the answers:

Question 1 : What are the databases supported by CodeFluent Entities?

  • Microsoft SQL Server
  • Microsoft SQL Azure
  • Oracle
  • MySQL
  • PostgreSQL
  • All those mentionned

Question 2 : How can we create Web service with CodeFluent Entities?

  • Creating a T4 template
  • Adding a producer
  • Handwriting

Question 3 : What is the continuous generation?

  • Apply model changes consistently to all layers without losing changes nor data
  • Generate the model in background each time the model is edited
  • The generation process never stop and use 100% of the CPU

Additional Information and References :

PostgreSQL Producer
MySQL Producer
Oracle Database Producer
Microsoft SQL Azure Producer
Microsoft SQL Server Producer
Documentation – Generating
Service Object Model Producer
Generating JSON Web Services from an Existing Database with CodeFluent Entities (Code Project)
Continuous generation (video)

The final draw took place on Febrary 26th, 2014 and the prize was awarded to Guillaume Spera.

Congratulations!


Using Microsoft Office as a Front-end

$
0
0

Using CodeFluent Entities you can generate synchronizable lists which lets you use Microsoft Office Excel (2003 and upper) and Microsoft Office Access (2007 and upper) as front-end clients of your application. This feature is actually discussed in this post: Introduction to SharePoint Lists. As a reminder the global architecture is illustrated in the following figure:

Office lists

Before creating the solution, let’s see what the user interface will look like:

Excel

Let’s create the solution

We’ll create 4 projects:

  • A CodeFluent Entities Model project
  • A Class Library project to store the Business Object Model
  • A Database project to store SQL scripts
  • An empty WebForm project to host the web site and web services

Projects

Now we can add some entities to the model:

Model

The Id must be of type int to be synchronized with Office, so don’t use Guid or anything else. I also add two computed properties: FullName and Age.

Then configure the following producers:

  • A SQL Server Producer
  • The Business Object Model (C#) Producer
  • The Office Producer: “Physical Root Path” and “Target directory” must be set to the web project

Now we can build the model. The code generated works with the ISAPI filter (the old way). But the new way is to use the HttpModule WssEmulator. So we just need to add the following piece of configuration in the web.config file to simulate SharePoint:

<system.webServer>
	<modules runAllManagedModulesForAllRequests="true">
		<add name="WssEmulator" type="CodeFluent.Runtime.Web.WssEmulator" />
	</modules>
	<validation validateIntegratedModeConfiguration="false" />
</system.webServer>

Working with Microsoft Access

Open Access and create a new blank database. Select SharePoint List from the External Data tab:

Access

Enter the root URL of your Office website. Access will show a list of available lists. Now choose the SharePoint lists you want to link to.

Access SharePoint

Now you can open and edit your data directly from Access:

Access Sync

Or maybe you prefer fill data in a form:

Access Forms

Now let’s to do the same thing but with Microsoft Excel! :)

Working with Microsoft Excel

To open a list in Excel you need an IQY file. This is an internet query file format used by Microsoft Excel to make queries over HTTP. CodeFluent Entities generates a web page that contains all available lists and allows you to download the IQY file associated. Launch the web project and navigate to http://localhost/en-us/lists.aspx:
Lists Web

Note that you can also generate IQY files by using the template located in “C:\Program Files (x86)\SoftFluent\CodeFluent\Modeler\Templates\OfficeServiceHost\ClientIqy”.

Select one of them to open your list in Microsoft Excel:

Excel Sync

If you are using Excel 2007 or above you may read this article: Restoring Two-Way Synchronization on SharePoint Lists Using Excel.

Points of interest

  • Full localization support: column name and enumeration values
  • Enumeration and relations are selectable through a drop-down list (relations show the DisplayName of the entity)
  • By default, relations load all values from the related entity. You can change that by setting the loadMethodName attribute cfpo:loadMethodName=”LoadMethodCustom”
  • Excel or Access ensures that values are valid. For example you can’t write a string into an integer column.
  • Blob columns show the file name. Click on one of them to download the related file
  • Rich string are saved as HTML. For example if you set test (bold) the following string will be save as <strong>Test</strong>
  • Some columns can be Read-only by setting the property Is Read Only in the model
  • Support HTTP and HTTPS
  • Support authentication (basic authentication, NTLM, Kerberos)
  • Allow to work offline
  • Create different views of the same entity

For example one for editing data and another one for viewing data. In the first one you can set FirstName, LastName and Date of birth. In the second one, you may prefer showing the full name and the age.

  • Parameterize your lists
LOAD(string name) 
WHERE FirstName STARTSWITH @name OR LastName STARTSWITH @name

A prompt will ask you the name parameter when you open the list. This is a way to filter the list.

Parameter Value

CodeFluent Entities provides out of the box a very quick way to generate a user friendly way to view and edit data.
Don’t forget that in Microsoft Office Excel 2007, 2010 & 2013, the ability to update the information in SharePoint lists from Excel is deprecated. Nevertheless, you should look at SharePoint List Synchronizer to address this issue and allow you to open and edit SharePoint Lists from Excel in two-way sync.

Happy synchronizing!

The R&D team.

The sample source code is available for download.


Viewing all 125 articles
Browse latest View live