Example: Creating a Rules Extension from Multiple Sources

One limitation of rules extensions for the metaverse is that there is only one assembly where all the work is done. This makes it difficult for a team of developers to work on a metaverse rules extension. This topic presents one technique that you can use to assign multiple developers to a metaverse rules extension.

The strategy behind this technique is to create additional assemblies on which other developers can work. Microsoft strongly recommends that however you partition the work, you should ensure that each provisioning extension operates on separate, disjoint objects. Failure to follow this rule can result in unpredictable provisioning.

For example, you could create two additional assemblies, MV_Extension_MA1.dll and MV_Extension_MA2.dll, through which you provision objects to management agents MA1 and MA2, respectively.

To identify your assembly as the metaverse rules extension, compile your code into an extension DLL and configure that DLL as the metaverse extension in the Configure Extensions dialog box.

The following code example uses multiple dynamic link libraries (DLLs) containing classes that implement the IMVSynchronization interface and its methods. The example loads any DLL it finds in the ExtensionsDirectory with the prefix "MV_Extension" and executes each of the DLL methods in the example's corresponding method.

Note  You can use a similar technique in a management agent rules extension if you want to have more than one developer work on the management agent rules extension.

The following example shows how to use a rules extension to utilize multiple provisioning DLLs:

    Imports System.IO
    Imports System.Reflection
    Imports Microsoft.MetadirectoryServices
    Imports Microsoft.MetadirectoryServices.Logging
    
    Public Class MVExtensionObject
        Implements IMVSynchronization
    
        Dim myMVDlls() As IMVSynchronization
        Dim PREFIX As String = "MV_Extension"
    
        Public Sub Initialize() Implements IMVSynchronization.Initialize
            ' Get list of files that start with PREFIX and have a .dll extension
            Dim fileNames() As String = Directory.GetFiles( _
                Utils.ExtensionsDirectory, _
                PREFIX + "*.dll")
    
            ' Create the array the size of the number of files we found.
            Dim numFiles As Int32 = fileNames.Length -1
    
            ReDim myMVDlls(numFiles)
    
            Dim i As Integer
            Dim fileName As String
            Dim assem As [Assembly]
            Dim type, types() As Type
            Dim objLoaded As Object
    
            ' Load the extension files into the array.
            For i = 0 To numFiles
    
                ' Load the assembly.
                fileName = fileNames(i)
                assem = [Assembly].LoadFrom(fileName)
    
                types = assem.GetExportedTypes()
    
                ' Examine all the object types in the assembly for
                ' ones that starts with "MVExtension". We assume
                ' this object type is an MV extension object type.
                For Each type In types
                    If (Not (type.GetInterface("Microsoft.MetadirectoryServices.IMVSynchronization") Is Nothing)) Then
                        ' Create an instance of the MV extension object type.
                        objLoaded = assem.CreateInstance(type.FullName)
                        Exit For
                    End If
                Next
    
                ' If an object type starting with "MVExtension" could not be found,
                ' or if an instance could not be created, throw an exception.
                If objLoaded Is Nothing Then
                    Throw New UnexpectedDataException("Found MV extension " + _
                        "DLL (" + fileName + ") without an " + PREFIX + "* type")
                End If
    
                ' Add this MV extension object to our array of objects.
                myMVDlls(i) = objLoaded
    
                ' Call the Initialize() method on each MV extension object.
                myMVDlls(i).Initialize()
            Next
        End Sub
    
        Public Sub Terminate() Implements IMVSynchronization.Terminate
            Dim myDll As IMVSynchronization
    
            ' Call the Terminate() method on each MV extension object.
            For Each myDll In myMVDlls
                myDll.Terminate()
            Next
        End Sub
    
        Public Sub Provision(ByVal mventry As MVEntry) Implements IMVSynchronization.Provision
            Dim myDll As IMVSynchronization
    
            ' Call the Provision() method on each MV extension object.
            For Each myDll In myMVDlls
                myDll.Provision(mventry)
            Next
    
        End Sub
    
        Public Function ShouldDeleteFromMV(ByVal csentry As CSEntry, _
            ByVal mventry As MVEntry) As Boolean _
            Implements IMVSynchronization.ShouldDeleteFromMV
    
            Dim myDll As IMVSynchronization
    
            Dim shouldDelete As Boolean = False
    
            ' Call the ShouldDeleteFromMV() method on each MV extension object.
            For Each myDll In myMVDlls
                If myDll.ShouldDeleteFromMV(csentry, mventry) Then
                    shouldDelete = True
                    Exit For
                End If
            Next
    
            ShouldDeleteFromMV = shouldDelete
        End Function
    End Class
    using System;
    using System.IO;
    using System.Reflection;
    using Microsoft.MetadirectoryServices;
    using Microsoft.MetadirectoryServices.Logging;
    
    namespace Miis_Metaverse
    {
        public class MVExtensionObject : IMVSynchronization
        {
            IMVSynchronization [] myMVDlls;
            string PREFIX = "MV_Extension";
    
            void IMVSynchronization.Initialize ()
            {
                // Get list of files that start with PREFIX and have a .dll extension
                string[] fileNames =
                    Directory.GetFiles(
                    Utils.ExtensionsDirectory,
                    PREFIX + "*.dll");
    
                int numFiles = fileNames.Length;
    
                // Create the array the size of the number of files we found.
                myMVDlls = new IMVSynchronization[numFiles];
    
                string   fileName;
                Assembly assem;
                Type[]   types;
                Object   objLoaded = null;
    
                // Load the extension files into the array.
                for(int i = 0; i < numFiles; i++)
                {
                    // Load the assembly.
                    fileName = fileNames[i];
                    assem    = Assembly.LoadFrom(fileName);
    
                    types = assem.GetExportedTypes();
    
                    // Examine all the object types in the assembly for
                    // ones that starts with "MVExtension". We assume
                    // this object type is an MV extension object type.
                    foreach(Type type in types)
                    {
                        if(type.GetInterface("Microsoft.MetadirectoryServices.IMVSynchronization") != null)
                        {
                            // Create an instance of the MV extension object type.
                            objLoaded = assem.CreateInstance(type.FullName);
                            break;
                        }
                    }
    
                    // If an object type starting with "MVExtension" could not be found,
                    // or if an instance could not be created, throw an exception.
                    if(null == objLoaded)
                    {
                        throw new UnexpectedDataException("Found MV extension " +
                            "DLL (" + fileName + ") without an " + PREFIX + "* type");
                    }
    
                    // Add this MV extension object to our array of objects.
                    myMVDlls[i] = (IMVSynchronization)objLoaded;
    
                    // Call the Initialize() method on each MV extension object.
                    myMVDlls[i].Initialize();
                }
            }
    
            void IMVSynchronization.Terminate ()
            {
                // Call the Terminate() method on each MV extension object.
                foreach(IMVSynchronization mvextension in myMVDlls)
                {
                    mvextension.Terminate();
                }
            }
    
            void IMVSynchronization.Provision (MVEntry mventry)
            {
                // Call the Provision() method on each MV extension object.
                foreach(IMVSynchronization mvextension in myMVDlls)
                {
                    mvextension.Provision(mventry);
                } 
            }
    
            bool IMVSynchronization.ShouldDeleteFromMV (CSEntry csentry, MVEntry mventry)
            {
                bool shouldDelete = false;
    
                // Call the ShouldDeleteFromMV() method on each MV extension object.
                foreach(IMVSynchronization mvextension in myMVDlls)
                {
                    if(mvextension.ShouldDeleteFromMV(csentry, mventry))
                    {
                        shouldDelete = true;
                        break;
                    }
                }
    
                return(shouldDelete);
            }
        }
    }

Send comments about this topic to Microsoft

Build date: 2/16/2009