FIM or MIM has many build in connectors which can be enhanced to connect to the source and bring the object in scope of FIM for automate user creation, provisioning and de-provisioning in Active Directory.

When there is a need to build out of the box FIM connectors, it’s possible to implement a custom Management Agent (MA) for FIM using .NET framework.
This article can be used for a reference only and guidance how to build ECMA 2.0 connectors in FIM for the beginner.

The below XML file is use to import the data in ECMA connector.




In Synchronization Manager, go to Management Agent Tab, Select Action and create extension Project, choose the option Extensible connectivity 2.0 Extension. it will give the default template where we can start implementing the business logic, Here we will write how to import the data of the above XML into FIM ECMA connector.

The Code is below

using System;
using System.IO;
using System.Xml;
using System.Text;
using System.Collections.Specialized;
using Microsoft.MetadirectoryServices;
using System.Collections.ObjectModel;
using System.Collections.Generic;
 
namespace FimSync_Ezma
{
    public class EzmaExtension :
    //IMAExtensible2CallExport,
    IMAExtensible2CallImport,
    //IMAExtensible2FileImport,
    //IMAExtensible2FileExport,
    //IMAExtensible2GetHierarchy,
    IMAExtensible2GetSchema,
    IMAExtensible2GetCapabilities
    //IMAExtensible2GetParameters,
    //IMAExtensible2GetPartitions
    {
 
        private int m_importDefaultPageSize = 12;
        private int m_importMaxPageSize = 50;
        public string proID;
        public string price;
        //
        // Constructor
        //
        public EzmaExtension()
        {
            //
            // TODO: Add constructor logic here
            //
        }
 
        public MACapabilities Capabilities
        {
            get
            {
                MACapabilities myCapabilities = new MACapabilities();
 
                myCapabilities.ConcurrentOperation = true;
                myCapabilities.ObjectRename = false;
                myCapabilities.DeleteAddAsReplace = true;
                myCapabilities.DeltaImport = true;
                myCapabilities.DistinguishedNameStyle = MADistinguishedNameStyle.None;
                myCapabilities.ExportType = MAExportType.AttributeUpdate;
                myCapabilities.NoReferenceValuesInFirstExport = false;
                myCapabilities.Normalizations = MANormalizations.None;
 
                return myCapabilities;
            }
        }
 
        public int ImportDefaultPageSize
        {
            get
            {
                return m_importDefaultPageSize;
            }
        }
 
        public int ImportMaxPageSize
        {
            get
            {
                return m_importMaxPageSize;
            }
        }
 
        public CloseImportConnectionResults CloseImportConnection(CloseImportConnectionRunStep importRunStep)
        {
            return new CloseImportConnectionResults();
        }
 
        public GetImportEntriesResults GetImportEntries(GetImportEntriesRunStep importRunStep)
        {
            List<CSEntryChange> csentries = new List<CSEntryChange>();
            GetImportEntriesResults importReturnInfo;
            XmlDocument xmlDoc = new XmlDocument();
            xmlDoc.Load("C:\\Users\\Administrator\\Desktop\\product.xml");
            XmlNodeList nodeList = xmlDoc.DocumentElement.SelectNodes("/Table/Product");
            string proID = "", proName = "", price = "";
            foreach (XmlNode node in nodeList)
            {
                proID = node.SelectSingleNode("Product_id").InnerText;
                proName = node.SelectSingleNode("Product_name").InnerText;
                price = node.SelectSingleNode("Product_price").InnerText;
                CSEntryChange csentry1 = CSEntryChange.Create();
 
                csentry1.ObjectModificationType = ObjectModificationType.Add;
                csentry1.ObjectType = "Person";
                csentry1.AttributeChanges.Add(AttributeChange.CreateAttributeAdd("product", proID));
                csentry1.AttributeChanges.Add(AttributeChange.CreateAttributeAdd("productprice", price));
                csentries.Add(csentry1);
 
                 
 
            }
 
            importReturnInfo = new GetImportEntriesResults();
            importReturnInfo.MoreToImport = false;
            importReturnInfo.CSEntries = csentries;
            return importReturnInfo;
        }
 
        public Schema GetSchema(KeyedCollection<string, ConfigParameter> configParameters)
        {
            Microsoft.MetadirectoryServices.SchemaType personType = Microsoft.MetadirectoryServices.SchemaType.Create("Person", false);
 
            //myname = configParameters["myname"].Value;
 
            string myattribute = "product";
            string myattributes = "productprice";
            if (myattribute == "product")
            {
                personType.Attributes.Add(SchemaAttribute.CreateAnchorAttribute(myattribute, AttributeType.String));
            }
            if(myattributes== "productprice")
            {
                personType.Attributes.Add(SchemaAttribute.CreateAnchorAttribute(myattributes, AttributeType.String));
            }
 
 
            Schema schema = Schema.Create();
            schema.Types.Add(personType);
 
            return schema;
        }
 
        public OpenImportConnectionResults OpenImportConnection(KeyedCollection<string, ConfigParameter> configParameters, Schema types, OpenImportConnectionRunStep importRunStep)
        {
            return new OpenImportConnectionResults();
        }
    };
}

Create the ECMA in Synchronization Manager and configure the run profile "Full Import".
Run the Full import and the data from XML file import in the ECMA connector.
After Full Import, there are 4 objects in ECMA Connector.



Hope this help someone in implementing ECMA connector, Best of Luck..!!