Home > Developing Using CodeFluent Entities, Producers > Dissecting the ASP.NET Identity Producer – Part 3

Dissecting the ASP.NET Identity Producer – Part 3


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.

  1. No comments yet.
  1. No trackbacks yet.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s