Archive

Posts Tagged ‘Producers’

Dissecting the ASP.NET Identity Producer – Part 3

June 24, 2014 Leave a comment

If you’ve read our two previous posts (Part 1 and Part 2), you should know how to create a CodeFluent Entities custom producer. Now you may ask yourself how to integrate it into Microsoft Visual Studio and how to debug it.

Visual Studio Integration

Fist, to declare the producer, we have to create or edit the xml file located in “%APPDATA%\CodeFluent.Modeler.Design”.

<codeFluent.Modeler> 
    <producerDescriptors> 
      <producerDescriptor name="AspNetIdentity" displayName="Asp.Net Identity" category="Security" typeName="SoftFluent.AspNetIdentity.AspNetIdentityProducer, SoftFluent.AspNetIdentity" /> 
    </producerDescriptors> 
</codeFluent.Modeler>

Then, open Visual Studio and try to add a new producer:

AspNet Identity Producer Configuration

The property grid displays properties exposed by the producer:

public class AspNetIdentityProducer : BaseProducer
{
    [DefaultValue(false)]
    [Category("Source Production")]
    [DisplayName("Must Implement IQueryableUserStore")]
    [Description("Determines if the IQueryableUserStore interface must be implemented. WARNING: this is not a real IQueryable data source. This can be used to load all users.")]
    [ModelLevel(ModelLevel.Normal)]
    public bool MustImplementQueryableUserStore
    {
        get
        {
            return XmlUtilities.GetAttribute(Element, "implementQueryableUserStore", false);
        }
        set
        {
            XmlUtilities.SetAttribute(Element, "implementQueryableUserStore", value.ToString().ToLowerInvariant());
        }
    }
}

As you can see, parameter values are stored in the XML file. Do not create automatic properties, it won’t work!

We show that we can create custom attributes, but it can be very useful to display them in the property grid:

Custom Producer Property Grid

The BaseProducer implements the IDescribable interface, so we have to override the BuildDescriptors method.

protected override void BuildDescriptors(IList<Descriptor> descriptors)
{
    if (descriptors == null)
        return;

    descriptors.Add(BuildDescriptor(
        name: "entityType",
        typeName: typeof(EntityType).AssemblyQualifiedName,
        defaultValue: "None",
        displayName: "Entity Type",
        description: "ASP.NET Identity Entity Type.",
        targets: NodeType.Entity));

    descriptors.Add(BuildDescriptor(
        name: "propertyType",
        typeName: typeof(PropertyType).AssemblyQualifiedName,
        defaultValue: "None",
        displayName: "Property Type",
        description: "ASP.NET Identity Property Type.",
        targets: NodeType.Property));

    descriptors.Add(BuildDescriptor(
        name: "methodType",
        typeName: typeof(MethodType).AssemblyQualifiedName,
        defaultValue: "None",
        displayName: "Method Type",
        description: "ASP.NET Identity Method Type.",
        targets: NodeType.Method));

    base.BuildDescriptors(descriptors);
}

Thanks to the target, descriptors are shown only when needed. This allow to not pollute the property grid with meaningless descriptors. Note that the same descriptor can have multiple targets. Combine them with OR (“|” in C#). For example :

 NodeType.Property | NodeType.Method.

Because creating identity entities is boring, we add a form to create them automatically:

AspNet Identity Form

The two issues are:

  • How to open this form?
  • How to edit the model?

To answer the first one, CodeFluent Entities uses another interface: IDesignProducer. It allows to add menu items at the producer level.

Create Identity Entities

Once again, the BaseProducer already implements this interface so we have to override two methods: EnumerateMenus and ExecuteMenu.

protected override void BuildMenus(IList<IDesignProducerMenu> menus)
{
    base.BuildMenus(menus);

    if (menus == null)
        return;

    menus.Add(new BaseDesignMenu("Create Identity Entities", true));
}

protected override bool ExecuteMenu(IServiceProvider serviceProvider, IDictionary<string, object> context, int index)
{
    Project project = context["Project"] as Project;
    if (project == null)
        return false;

    switch (index)
    {
        case 0:
            var form = new ConfigurationForm(project);
            form.ShowDialog();
            return true;
    }

    return base.ExecuteMenu(serviceProvider, context, index);
}

Now we open the form, we need to create entities. You can see that we have access to the Project object, so just use it. Here’s the code to create a new entity:

Entity entity = new Entity();
entity.Name = entityName;
entity.Namespace = @namespace;
entity.SetAttributeValue("", "entityType", Constants.NamespaceUri, entityType);
project.Entities.Add(entity);

When you edit the model, CodeFluent Entities automatically update surfaces.

How to debug your custom producer?

One way is to start Visual Studio as administrator, so you can use the post build event to copy the generated DLL to the CodeFluent Entities directory.

xcopy “$(TargetPath)” “C:\Program Files (x86)\SoftFluent\CodeFluent\Modeler” /Y

Then you can configure the debugger to start an external program:

Program: C:\Program Files (x86)\SoftFluent\CodeFluent\Modeler\CodeFluent.Build4.exe
Command line arguments:

Producer Debugger Configuration
Another solution is to add System.Diagnostics.Debugger.Launch and System.Diagnostics.Debugger.Break in your code. This can be useful in templates.

Now you can start the debug (F5) and set breakpoints into your producer.

To conclude, this producer is quite simple, but it shows:

  • How to extends the modeler,
  • How to edit the model at design time,
  • How to generate code with Templates and CodeDom.

This is a great start when you want to write a producer. If you need more information, feel free to ask your question on the forums.

The full source code is available on our GitHub repository.

Happy producing!

The R&D Team.

Dissecting the ASP.NET Identity Producer – Part 2

June 23, 2014 Leave a comment

In our last post, we talked about some generalities regarding writing a custom producer.
Today we’ll see how does the ASP.NET Identity Producer generate C# code. Let’s remind that the full source code is available on our GitHub repository.

First and before producing code, we have to find the Role and the User entities in the model.

Do you remember the NamespaceUri? It allows you to add custom attributes in the xml file which represents the model.

<cf:entity name="User" d2p1:entityType="User" xmlns:d2p1=
"http://www.softfluent.com/codefluent/producers.aspNetIdentityProducer/2014/1"> 

</cf:entity> 

We add the entityType attribute to the entity. Xml Namespace are useful to avoid naming conflict between producers.

To find the User entity we can do the following, create an enumeration named “EntityType”:

public enum EntityType 
{ 
    None, 
    User, 
    Role, 
    UserRole, 
    Claim, 
    Login 
} 

Then, read the attribute value in the following way:

foreach (var entity in project.Entities) 
{ 
    if (entity.GetAttributeValue("entityType", 
               Constants.NamespaceUri, EntityType.None) == EntityType.User) 
    { 
        return entity; 
    } 
} 

The Produce method is a blank method so you can do what you want. When the output file is simple (with no complex logic), the easiest way is to use a template. When the logic is more complex you may want to use other mechanism such as CodeDom.

In the ASP.NET Identity producer we decided to use two templates: one for UserRole and the other one for RoleStore. CodeFluent Runtime already provides everything you need to use template. We’ll use here the SimpleTemplateProducer abstract class to simplify templates mechanisms (loading, parsing, processing). This producer takes directly the template from the resources of the producer, so you’ll have only one DLL to release. Of course the template has access to the producer instance, and so to its properties and methods.

AspNet Identity Producer

Tips: Keep the maximum of the logic in the producer, your templates will be much simpler to read

Here’s an extract from the template:

public System.Threading.Tasks.Task CreateAsync([%=TemplateProducer.IdentityRole.Entity.ClrFullTypeName%] role)
{
	if(role == null)
		throw new System.ArgumentNullException("role");

    return System.Threading.Tasks.Task.FromResult(role.Save());
}

And the code to run the template

public class RoleStoreProducer : SimpleTemplateProducer
{
    public IdentityRole IdentityRole { get; set; }
    
    protected override string DefaultNamespace
    {
        get { return Producer.Project.DefaultNamespace + Producer.WebNamespaceSuffix + ".Security"; }
    }

    protected override string DefaultTypeName
    {
        get { return "RoleStore"; }
    }

    protected override Template CreateTemplate()
    {
        var template = base.CreateTemplate();

        template.AddReferenceDirective(typeof(CodeDomBaseProducer));
        template.AddReferenceDirective(typeof(UserStoreProducer));

        return template;
    }

    public override string TargetPath
    {
        get
        {
            string path = ConvertUtilities.Nullify(XmlUtilities.GetAttribute(Producer.Element, ConvertUtilities.Camel(this.TargetName) + "TargetPath", (string)null), true);
            if (path == null)
                return BaseType.GetFilePath(Producer.TargetBaseNamespace, TypeName, Namespace, Producer.FullTargetDirectory, null);

            return Producer.GetFullRelativeDirectoryPath(path);
        }
    }
}

Note: We omit some code to make this implementation simpler

The template file is found based on the DefaultTypeName, so we don’t need to specify anything else. Instantiating the RoleStoreProducer and calling its Produce method will load the template from resources, and run it.

To implement the IUser and IRole interfaces, we need to edit the code generated by the CodeDom Producer. To do so, the way to go is to write a CodeDomSubProducer. But you can also get the instance of the BOM producer and register to the CodeDomProduction event:

var producer = project.Producers.GetProducerInstance<CodeDomProducer>();
if (producer == null)
    return;
producer.CodeDomProduction += CodeDomProducer_CodeDomProduction;

We can now handle the event and add the interface implementation:

private void CodeDomProducer_CodeDomProduction(object sender, CodeDomProductionEventArgs e)
{
    if (e.EventType == CodeDomProductionEventType.EntityCommitting)
    {
        CodeCompileUnit unit = e.Argument as CodeCompileUnit;
        if (unit == null)
            return;

        foreach (CodeNamespace ns in unit.Namespaces)
        {
            foreach (CodeTypeDeclaration typeDeclaration in ns.Types)
            {
                BaseType type = UserData.GetBaseType(typeDeclaration);
                if (type.GetAttributeValue("entityType", NamespaceUri, EntityType.None) == EntityType.User)
                {
                    // Implements IUser<TKey> & IUser
                    if (_identityUser.MustImplementGenericInterface)
                    {
                        ImplementIUser(typeDeclaration, true);
                    }

                    ImplementIUser(typeDeclaration, false);
                }
            }
        }
    }
}

private void ImplementIUser(CodeTypeDeclaration typeDeclaration, bool generic)
{
    string keyTypeName = generic ? _identityUser.KeyTypeName : typeof(string).FullName;
    var iuserCodeTypeReference = new CodeTypeReference("Microsoft.AspNet.Identity.IUser");
    var iuserGenericCodeTypeReference = new CodeTypeReference("Microsoft.AspNet.Identity.IUser");
    iuserGenericCodeTypeReference.TypeArguments.Add(keyTypeName);
    if (generic)
    {
        iuserCodeTypeReference.TypeArguments.Add(keyTypeName);
    }

    typeDeclaration.BaseTypes.Add(iuserCodeTypeReference);

    CodeMemberProperty idProperty = new CodeMemberProperty();
    idProperty.PrivateImplementationType = iuserGenericCodeTypeReference;
    idProperty.Type = new CodeTypeReference(keyTypeName);
    idProperty.Name = "Id";
    idProperty.HasSet = false;
    idProperty.GetStatements.Add(new CodeMethodReturnStatement(new CodePropertyReferenceExpression(new CodeThisReferenceExpression(), generic ? _identityUser.KeyPropertyName : "EntityKey")));
    typeDeclaration.Members.Add(idProperty);
}

The CodeDom can be traversed to find class declarations. The CodeDom producer annotates CodeDom elements, so we can get model concept from the CodeDom element by using UserData class. In this case we know if a class corresponds to the User entity by using UserData.GetBaseEntity.

In the last part, we’ll explain how to integrate this producer in Visual Studio and how to debug it.

The R&D Team.

Dissecting the ASP.NET Identity Producer – Part 1

June 19, 2014 Leave a comment

A few weeks ago we release a new producer: ASP.NET Identity Producer. Let’s see how we wrote it.

The main idea of the article is not to explain every line of code, but to explain the main concepts of the producer.

As a reminder the full source code of the producer is available on our GitHub repository.

What is a producer?

The main goal of a producer is to translate the model into code of any kind: C#, VB.NET, SQL, plain text. But a producer can generate what it want, or maybe don’t generate anything. It can also interact with database or file system.  You can do what you want with a producer.

First you have to implement the interface IProducer.

public interface IProducer 
{ 
    event Producer.OnProductionEventHandler Production; 
    void Initialize(Project project, Producer producer); 
    void Produce(); 
    void Terminate(); 
}

The build process uses producer this way:

Build Process

In the Initialize method you should make required initializations. Often this method simply copy the Project parameter to a field, so it can be used in the Produce method. The project object contains all information about the model (Entities, Views, Tables, etc.).

In the Produce method, you have to generate the output. This can be a complex output as the BOM or a much simpler as a summary of the project or maybe no output.
The Terminate method allows to clean resources.

This is the theory. In practice producers often inherit from a base class which already implement the IProducer interface:

  • BaseProducer
  • UIProducer
  • CodeDomBaseProducer
  • TemplateProducer
  • any existing producer

The basic code of the ASP.NET Identity producer is:

public class AspNetIdentityProducer : BaseProducer
{
    protected override string NamespaceUri
    {
        get { return Constants.NamespaceUri; }
    }

    public Version TargetFrameworkVersion
    {
        get
        {
            return new Version(4, 5);
        }
    }

    public override void Initialize(Project project, Producer producer)
    {
        base.Initialize(project, producer);
    }

    public override void Produce()
    {
    }
}

public class Constants
{
    public const string NamespaceUri = "http://www.softfluent.com/codefluent/producers.aspNetIdentityProducer/2014/1";
}

We introduce two additional notions: TargetFrameworkVersion and NamespaceUri.

The first one is the Framework version needed by the generated code. The second one is the NamespaceUri used to store custom xml attributes. You should create a unique name.

How to deploy and use the producer?

A producer is composed of one DLL that contains a class which implements IProducer. To deploy the producer, you must copy the DLL to the CodeFluent Entities directory (by default: C:\Program Files (x86)\SoftFluent\CodeFluent\Modeler). To use it, you have to declare it in the model file:

  <cf:producer name="Asp.Net Identity" typeName="CodeFluent.Producers.AspNetIdentity.AspNetIdentityProducer, CodeFluent.Producers.AspNetIdentity">
    <cf:configuration targetDirectory="..\Samples" implementQueryableUserStore="true" implementQueryableRoleStore="true" cfx:targetProjectLayout="Update" />
  </cf:producer>

The next post will cover how does the producer generate the code. In the meantime you can download the full code on our GitHub repository.

Let us know what you think!

The R&D Team.

ASP.NET Identity Producer


CodeFluent Entities can generate out of the box Membership, Role & Profiles Providers. Recently Microsoft release a new Identity system: ASP.NET Identity. As it seems to be more and more use, we decided to write a new producer to support this new Identity system.

First of all, the source code of the producer is available on our GitHub repository.

The producer does two things:

  • It assists you in creating ASP.NET Identity entities (User, Role, Claim, Login)
  • It generates the UserStore and RoleStore and implements IUser and IRole

How to install

  • Download the code from GitHub and compile it. A compiled version is also available here
  • Copy the output “CodeFluent.Producers.AspNetIdentity.dll” to “C:\Program Files (x86)\SoftFluent\CodeFluent\Modeler”
  • (Optional) To integrate the producer to the graphical modeler copy or merge “custom.config” to “%APPDATA%\CodeFluent.Modeler.Design\custom.config”

How to use it

  1. Create a CodeFluent Entities project
  2. Add a Business Object Model (BOM) producer
  3. Add this new producer (Security -> Asp.Net Identity). Note: The target path has no effect. The target path will be “Target Path of the BOM Producer\Web\Security(User|Role)Store”
  4. Add New Producer

  5. Right click on the producer and click the “Create Identity Entities” menu item
  6. Create Identity Entities

  7. Select necessary entities (User, Role, Claim, Login) and the destination namespace
  8. ASP.NET Identity

  9. Customize entities. For example you can remove “Password” property if you don’t need it
  10. ASP.NET Identity Model

  11. Generate and use the code :)

Note: you must add the “Microsoft.AspNet.Identity.Core” Nuget package before compiling the generated code (but this is obvious).

CodeFluent Entities is very extensible. As we try to show in this article, one way of extending it is by using producers. Of course the main goal of producers is to generate code. But they can also interact with the model at design time thanks to the CodeFluent Entities API.

Please share your feedbacks about this producer and don’t hesitate to make some suggestion.

Happy coding!

The R&D Team.

Categories: Producers Tags: ,

And the winner is…

February 27, 2014 Leave a comment

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!

The new SQL Server Pivot Script producer

October 10, 2013 1 comment

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.

Using the SQL Server Template Producer to generate Clustered Indexes

November 27, 2012 Leave a comment

In this post we’ll see how using CodeFluent Entities’ SQL Server Template Producer, you can generate SQL scripts using  the built-in template engine whilst accessing the inferred meta-model, and then automatically deploy the generated script on your desired server.

By default SQL Azure and SQL Server add the clustered index on the primary key if a clustered index on the table does not already exist and if you do not specify a unique nonclustered index. In the case where the primary key is of GUID type it won’t be efficient. The reason for this is that GUIDs are generated in non-sequential order and SQL Server orders a clustered index sequentially. It will work – SQL Server will let you build a clustered index around a unique identifier column, however it will cause the SQL Server to do unnecessary work and cause performance slowdowns.

That being said, what we can do is using the SQL Template Producer to remove all inefficient clustered indexes and recreate them on the right columns. Let’s even go a bit further and create a little aspect that will add a property on each property to tell if a clustered index needs to be created or not on that particular property.

Add a new Part called IsClusteredIndexAspect and past it the following code (replacing the defaultNamespace’s value by yours):

<cf:project xmlns:cf=”http://www.softfluent.com/codefluent/2005/1” defaultNamespace=”yourNamespace”>

<cf:pattern name=”IsClusteredIndex Aspect” namespaceUri=”http://www.sample.com/aspects/isclusteredindexaspect/2012/11” preferredPrefix=”sa” step=”Tables”>

<cf:message class=”_doc”>
This aspect creates an extra IsClusteredIndex bool property on every property.
</cf:message>

<cf:descriptor name=”IsClusteredIndex” typeName=”boolean” targets=”Property” defaultValue=”false” displayName=”IsClusteredIndex” description=”Should the IsClusteredIndex Aspect apply to this property?” />

</cf:pattern>
</cf:project>

This will create our aspect and add a IsClusteredIndex property on each property in the “Aspects and Producers” property grid:

image

You can by now choose which property you want to use as a clustered index. Obviously this property should be set to true only on one property by entity since clustered index cannot be applied on several columns.

Now let’s write a script that will remove all clustered indexes and then create new ones based on the columns selected thanks to our aspect. In a file called “[Template]CreateIndexes.sql” add it the following code (Note that this code is only an illustration for this post, it does not take into account constraints, primary keys and so on):

[%@ namespace name="CodeFluent.Model"%]
[%@ namespace name="CodeFluent.Model.Persistence"%]
[%@ namespace name="CodeFluent.Producers.SqlServer"%]
/* [%=Producer.GetSignature()%] */

[%foreach (Entity e in Producer.Project.Entities)
{%]
    --remove any existing clustered index on e.Table.FullName
    --[...]
  
   [%foreach (Property p in e.Properties)
    {
        if (p.GetAttributeValue("sa:IsClusteredIndex", false))
        {%]      
        --create your index such as:
        CREATE CLUSTERED INDEX [CL_[%=p.Entity.Table.Name%]] ON [%=p.Entity.Table.FullName%] ([[%=p.Column.Name%]]);
        GO
        [%}
    }
}%]

 

Create a folder called “Template” under the file folder of your CodeFluent Entities project:

image

Right click on that folder and choose “Add existing item” then browse to your template file and select it.

Now in your CodeFluent Entities project, add an instance of the SQL Server Template Producer with your Template directory as the “Source Directory” and set the “Target Directory” to the project of you choice and then build over your model. The SQL Server Template Producer will generate a script file from your template, and run the script on the server removing and creating clustered indexes. Therefore using the template producer you can quickly create complex scripts by taking advantage of the meta model.

 

Cheers,

Thibault NESTOR

Follow

Get every new post delivered to your Inbox.

Join 49 other followers