0

I want the plugins to trigger automatically. Does the FakeXrmEasy support this ? I tried following - plugin:

    public class Foo : IPlugin
    {
        public void Execute(IServiceProvider serviceProvider)
        {
            // never breaks here
        }
    }


    public static EntityMetadata SetObjectTypeCode(EntityMetadata metadata, int value)
    {
        var property = typeof(EntityMetadata).GetProperty(nameof(metadata.ObjectTypeCode));
        property.SetValue(metadata, value);
        return metadata;
    }


    static void Main(string[] args)
    {
        var context = new XrmFakedContext();
        context.InitializeMetadata(SetObjectTypeCode(new EntityMetadata
        {
            LogicalName = "account",
        }, 1));

        context.RegisterPluginStep<Foo>("Create", primaryEntityTypeCode: 1);
        context.GetOrganizationService().Create(new Entity("account", Guid.NewGuid()));
    }

But the plugin is never executed.

Ondrej Svejdar
  • 19,236
  • 4
  • 49
  • 77

2 Answers2

1

That's because the framework internally use the EntityTypeCode field of the entity to get the registered plugins.

This field is not part of the Entity base class but is present on the early bound classes generated by crmsvcutil.

Also, the UsePipelineSimulation property of the XrmFakedContext instance is false by default so no plugin would run, you have to set it to true.

colinD
  • 650
  • 8
  • 13
  • I see - so the framework is making strong assumption of everyone using the crmsvcutil tool. That doesn't seem like a wise design choice - using LogicalName of entity would be more closer to how platform really works. – Ondrej Svejdar Mar 16 '20 at 21:41
  • 1
    Actually the CRM does [use](https://docs.microsoft.com/en-us/dynamics365/customerengagement/on-premises/developer/entities/sdkmessagefilter#BKMK_PrimaryObjectTypeCode) this type code to filter skdmessages. I think the missing link here is that when the type code is not provided, the testing framework does not search into metadata. – colinD Mar 17 '20 at 11:35
0

If anyone is interested the final snippet looks like:

var context = new XrmFakedContext { UsePipelineSimulation = true };
context.RegisterPluginStep<Foo, Account>("Create", ProcessingStepStage.Postoperation);
var organizationService = context.GetOrganizationService();
organizationService.Create(new Account { LogicalName = "account" });

And entity metadata (all) have to be accounted for like:

[EntityLogicalNameAttribute("account")]
public class Account : Entity
{
    [AttributeLogicalName("name")]
    public string Name { get; set; }

    public int EntityTypeCode;

    public Account()
    {
        this.EntityTypeCode = 1;
    }
}

Including system-only metadata:

[EntityLogicalName("plugintype")]
public class PluginType : Entity
{
    [AttributeLogicalName("plugintypeid")]
    public Guid PluginTypeId { get; set; }

    [AttributeLogicalName("name")]
    public string Name { get; set; }

    [AttributeLogicalName("typename")]
    public string TypeName { get; set; }

    [AttributeLogicalName("assemblyname")]
    public string AssemblyName { get; set; }

    [AttributeLogicalName("major")]
    public int Major { get; set; }

    [AttributeLogicalName("minor")]
    public int Minor { get; set; }

    [AttributeLogicalName("version")]
    public string Version { get; set; }
}


[EntityLogicalName("sdkmessage")]
public class SdkMessage : Entity
{
    [AttributeLogicalName("sdkmessageid")]
    public Guid SdkMessageId { get; set; }

    [AttributeLogicalName("name")]
    public string Name { get; set; }
}


[EntityLogicalName("sdkmessagefilter")]
public class SdkMessageFilter : Entity
{
    [AttributeLogicalName("sdkmessagefilterid")]
    public Guid SdkMessageFilterId { get; set; }

    [AttributeLogicalName("primaryobjecttypecode")]
    public int PrimaryObjectTypeCode { get; set; }
}


[EntityLogicalName("sdkmessageprocessingstep")]
public class SdkMessageProcessingStep : Entity
{
    [AttributeLogicalName("configuration")]
    public string Configuration { get; set; }

    [AttributeLogicalName("eventhandler")]
    public EntityReference EventHandler { get; set; }

    [AttributeLogicalName("sdkmessageid")]
    public EntityReference SdkMessageId { get; set; }

    [AttributeLogicalName("sdkmessagefilterid")]
    public EntityReference SdkMessageFilterId { get; set; }

    [AttributeLogicalName("filteringattributes")]
    public string FilteringAttributes { get; set; }

    [AttributeLogicalName("mode")]
    public OptionSetValue Mode { get; set; }

    [AttributeLogicalName("stage")]
    public OptionSetValue Stage { get; set; }

    [AttributeLogicalName("rank")]
    public int Rank { get; set; }
}
Ondrej Svejdar
  • 19,236
  • 4
  • 49
  • 77