jordimontana82 / fake-xrm-easy

The testing framework for Dynamics CRM and Dynamics 365 which runs on an In-Memory context and deals with mocks or fakes for you
https://dynamicsvalue.com/get-started/overview?source=git
Other
263 stars 182 forks source link

Expose Metadata generation #557

Open janssen-io opened 3 years ago

janssen-io commented 3 years ago

Purpose

This PR moves the bulk of the MetadataGenerator into a new static class CrmSvcUtilMetadataGenerator. This class is publicly exposed so that it can be used by projects to generate their own metadata.

This addresses the enhancement proposal #555.

Example use case:

A project using FakeXrmEasy generates Early Bound entities using a 3rd party tool that also includes the PrimaryNameAttribute. FakeXrmEasy does not read this data from the early bound entities as it's not generated by CrmSvcUtil.

The developers of the project can then write their own MetadataGenerator that makes use of the exposes FakeXrmEasy.Metadata.CrmSvcUtilMetadataGenerator.

internal static class MetadataGeneratorWithPrimaryAttributeName
{
    internal static List<EntityMetadata> GenerateMetadata(Assembly earlyBoundAssembly) 
    {
        // Newly exposed metadata generator that updates the EntityMetadata reference for a single entity Type.
        var crmSvcUtilMetaGen = new FakeXrmEasy.Metadata.CrmSvcUtilMetadataGenerator();

        List<EntityMetadata> entityMetadatas = new List<EntityMetadata>();
        foreach (Type earlyBoundEntity in earlyBoundEntitiesAssembly.GetTypes())
        {
            EntityLogicalNameAttribute entityLogicalNameAttribute = earlyBoundEntity.GetCustomAttribute<EntityLogicalNameAttribute>();
            if (entityLogicalNameAttribute == null) continue;

            EntityMetadata metadata = new EntityMetadata();

            FakeXrmEasy.Metadata.CrmSvcUtilMetadataGenerator.SetMetadata(metadata, earlyBoundEntity, entityLogicalNameAttribute);

            // The custom stuff we want to add: add PrimaryAttributeName in the Metadata
            FieldInfo primaryNameAttribute = earlyBoundEntity.GetField("PrimaryNameAttribute", BindingFlags.Static | BindingFlags.Public);
            if (primaryNameAttribute != null)
            {
                metadata.SetFieldValue("_primaryNameAttribute", primaryNameAttribute.GetValue(null));
            }

            entityMetadatas.Add(metadata);
        }
    }

}

// And then use it like this:
var metadata = MetadataGeneratorWithPrimaryAttributeName.GenerateMetadata(Assembly.GetAssembly(typeof(Contact)));
var context = new XrmFakedContext();
context.InitializeMetadata(metadata);