NGWS SDK Documentation  

This is preliminary documentation and subject to change.
To comment on this topic, please send us email at ngwssdk@microsoft.com. Thanks!

IConfigTransformer Interface

Implemented by platform and application developers that need to define their own configuration file hierarchy.

IConfigTransformer

[Visual Basic]
Public Interface IConfigTransformer
[C#]
public interface IConfigTransformer
[C++]
public __gc __interface IConfigTransformer

[JScript] In JScript, you can use the interfaces in the NGWS frameworks, but you cannot define your own.

Remarks

Transforms a request for configuration information into any other configuration request.

A use for transformer interceptors is a simple mapping of logical names (Selectors) to physical names.

Another common use for transformer interceptors is the computation of a hierarchy of configuration files: the interceptor receives the request for a simple selector (i.e. a FileSelector or HttpSelector) and turns it into a Interceptors.ListSelector. The ListSelector contains an ordered list of other Selector instances, that represent the result of the hierarchy computation. When the ConfigManager receives a ListSelector, it retrieves the configuration information (IConfigCollection) for each of the selectors in the list, and then invokes an Interceptors.IConfigMerger on pairs of configuration collections.

In order for the ConfigManager to be able to invoke interceptors, they must be declared in the MWIRING.XML file in the machine configuration directory. The MWIRING.XML file contains mappings of ConfigType and selector prefix to one or more interceptors to invoke for this combination.

Requirements

Namespace: System.Configuration.Interceptors

Assembly: System.Configuration.dll

Example [C#]

This example Web Server hierarchy interceptor computes the location of config.web files across the hierarchy of a URL, using IIS metabase information to perform URL to file name mapping:

[C#]

namespace Microsoft.Configuration.Samples {

using System;
using System.Configuration;
using System.Configuration.Interceptors;
using System.Configuration.Internal;
using System.DirectoryServices;
using System.Web;

using Microsoft.Configuration.Samples;

public class WebHierarchyInterceptor : IConfigTransformer {

    public RequestParams Transform(String configType, Selector selector, int los){

HttpFileSelector urlunc = null;

RequestParams reqparam = new RequestParams();
reqparam.configType = configType;
reqparam.selector   = new ListSelector();
reqparam.los        = los;

String url = ((HttpSelector)selector).ToString();

String[] Urls = IISAdminHelper.GetParentUrlsForUrl(url);
String[] UNCs = IISAdminHelper.GetParentPathsForUrl(url);

// Add the machine config file location
urlunc = new HttpFileSelector(
    new HttpSelector(Urls[0]), 
    new FileSelector("file://"+ConfigManagerHelper.GetMachineConfigDirectory() +"..\\config.web"));

Console.WriteLine("Adding: "+urlunc);
((ListSelector)(reqparam.selector)).Add(urlunc);

for (int i=0; i<Urls.Length; i++) {
    urlunc = new HttpFileSelector(new HttpSelector(Urls[i]), new FileSelector("file://"+UNCs[i]+"\\config.web"));
    Console.WriteLine("Adding: "+urlunc);
    ((ListSelector)(reqparam.selector)).Add(urlunc);
}

return reqparam;

        } // Transform

    } // class Hierarchy Interceptor
    

}

namespace Microsoft.Configuration.Samples {

using System;
using System.Configuration.Internal;
using System.DirectoryServices;
using System.Web;


/// <summary>
///    <para>
///       This class facilitates access to the IIS Metabase
///    </para>
/// </summary>
public class IISAdminHelper {

    /// <summary>
    ///    <para>
    ///      Returns the SiteID for a URL
    ///    </para>
    /// </summary>
    public static int GetSiteIDForUrl(String Url) {
        // TODO: Look up ServerBindings to get other than the default Site
        return 1; 
    }

    /// <summary>
    ///    <para>
    ///      Returns the physical path for a URL based on IIS metabase configuration
    ///    </para>
    /// </summary>
    public static String GetPathForUrl(String Url) {
        String relUrl= new HttpUrl(Url).Path;
        String relPath="";
        String LastVDIR = null;
        int lastPathElement = 0;

        String MBRootPath = "IIS://LocalHost/W3SVC/"+GetSiteIDForUrl(Url)+"/ROOT";

        DirectoryEntry d = new DirectoryEntry();

        while (true) {

d.Path=MBRootPath;
if (relUrl!="/") d.Path=d.Path+relUrl;

LastVDIR = null;
try {
    LastVDIR = (String) d.Properties["Path"].Value;
}
catch {
    LastVDIR= null;
}

if (LastVDIR != null) {
    if (LastVDIR.EndsWith("\\")) {
        return LastVDIR + relPath.Substring(1);
    }
    return LastVDIR + relPath;
}

lastPathElement=relUrl.LastIndexOf('/');
if (lastPathElement>=0) {
    relPath="\\"+relUrl.Substring(lastPathElement+1)+relPath;
    relUrl=relUrl.Substring(0,lastPathElement);
}
else
{
    throw(new ApplicationException("No physical directory defined for Url " + Url));
}
        } 
    }

    /// <summary>
    ///    <para>
    ///      Returns the machince configuration file, the physical paths for all parent nodes of a Url and the URL itself
    ///    </para>
    /// </summary>
    public static String[] GetParentPathsForUrl(String Url) {

        String[] parentUrls = GetParentUrlsForUrl(Url);

        String[] parentPaths = new String[parentUrls.Length];

        for (int i=0; i<parentUrls.Length; i++) {
parentPaths[i]=GetPathForUrl(parentUrls[i]);
        }
        return parentPaths;
    }

    /// <summary>
    ///    <para>
    ///      Returns the parent URLs for a URL.
    ///    </para>
    ///    <example>
    ///      Example:
    ///        GetParentUrlsForUrl("http://foo/bar/zee"), returns an array containing "http://foo", "http://foo/bar", "http://foo/bar/zee".
    ///    </example>
    /// </summary>
    public static String[] GetParentUrlsForUrl(String Url) {
        int i=0;
        HttpUrl parsedUrl = null;
        HttpUrl nextUrl = null;
        String pathToParse=null;
        String pathEaten="";
        int firstPathElement=0;

        // BUGBUG make this work for arbitrary URLs...
        String[] Urls = new String[100];

        parsedUrl = new HttpUrl(Url);
        pathToParse = parsedUrl.Path;

        i=0;

        //pathToParse=pathToParse.Substring(1); // skip initial "/"
        nextUrl = new HttpUrl(parsedUrl.Protocol, parsedUrl.Host, parsedUrl.Port, pathEaten, null, null);
        Urls[i]=nextUrl.ToString();
        i++;

        if (pathToParse!="/") {
while (pathToParse!=null) {

    firstPathElement=pathToParse.IndexOf('/',1);
    Console.WriteLine(":"+pathToParse+":"+pathEaten+":"+firstPathElement);
    if (firstPathElement>=0) {
        pathEaten=pathEaten+pathToParse.Substring(0, firstPathElement);
        pathToParse=pathToParse.Substring(firstPathElement);
    }
    else
    {
        pathEaten=pathEaten+pathToParse;
        pathToParse=null;
    }
    nextUrl = new HttpUrl(parsedUrl.Protocol, parsedUrl.Host, parsedUrl.Port, pathEaten, null, null);
    Urls[i]=nextUrl.ToString();
    i++;
}
        }

        String[] urlresult = new String[i];
        //BUGBUG use 
        // Copy(urlresult, Urls, i) as soon as it becomes available
        for (int j=0; j<i; j++) {
urlresult[j]=Urls[j];
        }
        return urlresult;
    }
}

}

MWIRING.XML entries:

<?xml version="1.0"?>
<configuration xmlns="x-schema:catalog.xms">

    <ManagedWiring>

        <Intercept  ConfigType="httphandlers" Protocol="http" Order="1"
        InterceptorClass="Microsoft.Configuration.Samples.WebHierarchyInterceptor"
        InterceptorType="Transformer" />
        <Intercept  ConfigType="httphandlers" Protocol="list" Order="2"
        InterceptorClass="System.Configuration.Interceptors.ListMerge"
        InterceptorType="Merger" />

    </ManagedWiring>

</configuration>

Place config.web files into the root directory of the default web site (typically c:\inetpub\wwwroot\config.web) and any subdirectories:

<configuration>

    <httphandlers>
        <remove verb="DEBUG" path="*" />
        <remove verb="*" path="trace.axd" />
    </httphandlers>

</configuration>

You can now run the following code to retrieve the httphandlers for a specific URL node, even when not running within an ASP+ request:

[C#]

using System.Configuration;
using System.Configuration.Core;

IConfigCollection httphandlers= ConfigManager.Get("httphandlers", "http://localhost");
foreach (System.Configuration.Web.HttpHandler handler in httphandlers) 
{
  Console.WriteLine(handler.verb + handler.path + handler.type);
}

See Also

IConfigTransformer Members | System.Configuration.Interceptors Namespace