Monday, June 23, 2008

XSL Transformations in .NET 2.0



Introduction
The core XSLT related classes are contained in the System.Xml.Xsl namespace, and are as follows:
XslCompiledTransform - Core class that acts as the XSLT processor in .NET Framework 2.0. Used to transform XML data into other structures such as HTML, text, or another XML.
XsltArgumentList - Allows you to pass a variable number of parameters and extension objects to an XSL style sheet.
XsltCompileException - This exception is thrown by the Load() method when an error occurs in the XSL style sheet.
XsltException - This exception is thrown if an exception occurs during the processing of an XSL style sheet.
Note that the XslTransform class used for XSL transformations in .NET Framework 1.x is now obsolete, and replaced by the new XslCompiledTransform class. In addition to better performance, the XslCompiledTransform also provides better support for the XSLT 1.0 specification. Starting from .NET Framework 2.0, the recommended approach to performing XSL transformations is through the XslCompiledTransform class. Because of the similarity in design to the XslTransform class, you can easily migrate your existing code to utilize the XslCompiledTransform class.
Before looking at the code sample, let us have a brief look at the important methods of the XslCompiledTransform class that will be required.
Load - This method has several overloads, and it provides for loading of an XSL stylesheet into an XslCompiledTransform object from any one of the following resources: a string that specifies the URL, from an XmlReader object, or from an XPathNavigator object, and so on.
Transform - Allows you to transform the XML data into a specified format using the stylesheet that is already loaded (using the Load method).
Implementation
Now that you have had an overview of the XSLT classes and the methods, let us start by looking at a simple XSL transformation example. For the purposes of this article, you will retrieve the data from AdventureWorks database in the form of XML data, and transform it using XSLT to render the data as HTML in the browser.
Simple XSL Transformation
In this example, you will create a simple ASP.NET page that retrieves categories data from the DB as an XML stream and transforms that into HTML so that it can be displayed in the browser. Before looking at the ASP.NET page, let us look at the XSL file named Category.xsl.
Collapse








Simple XSLT Transformation














center










The XSL file basically contains the logic to loop through all the elements contained in the Categories element. The code for the ASP.NET page is as follows:<%@ Page Language="C#" %>
<%@ Import Namespace="System.Data.SqlClient" %>
<%@ Import Namespace="System.Xml" %>
<%@ Import Namespace="System.Xml.Xsl" %>
<%@ Import Namespace="System.Xml.XPath" %>
<%@ Import Namespace="System.Web.Configuration" %>

In the Page_Load event of the Web form, you retrieve the data (in the form of XML) from the ProductSubcategory table, and then apply an external XSLT stylesheet (named Category.xsl) on the XML data, to emit HTML. You then write this HTML directly onto the client browser. This is accomplished by passing in the Response.Output object to the Transform() method. Note that in the above example, the XPathDocument class is used for loading the XML document, because this class is optimized to provide high-performance XML document processing. If you navigate to the page using the browser, you will see the output below.
Passing Parameters to an XSLT Stylesheet
Similar to the way you pass parameters to a method or a function, you can also pass parameters to an XSLT stylesheet. Passing a parameter to a stylesheet gives you the ability to initialize a globally scoped variable, which is defined as any that is a child of the element. The code shown in bold shows the lines of code where the parameter is declared and then used:
Collapse









Passing Parameters to an XSLT Style Sheet

















center










After the declaration of the BackGroundColor parameter, the code then uses the BackGroundColor parameter to specify the background color for the element in the table.
Although the value of BackGroundColor was hard-coded in the declaration using the <> element, ideally it should be passed from the calling ASP.NET page. To accomplish this, you leverage the XsltArgumentList class. Specifically, the AddParam() method of the XsltArgumentList provides this functionality. The XsltArgumentList class is a key class that enables you to create XSLT reusable and maintainable style sheets by providing a mechanism to pass parameters to an XSLT stylesheet.
To the AddParam() method, you supply a qualified name, the namespace URI, and a value. If the parameter value is not a String, Boolean, Number, NodeFragment, or NodeSet, it will be forced to a double or string. The ASP.NET calling page that passes parameters to the stylesheet is shown below:
Collapse<%@ Page Language="C#" %>
<%@ Import Namespace="System.Data.SqlClient" %>
<%@ Import Namespace="System.Xml" %>
<%@ Import Namespace="System.Xml.Xsl" %>
<%@ Import Namespace="System.Xml.XPath" %>
<%@ Import Namespace="System.Web.Configuration" %>

The above code is very similar to the first example except for the difference that this example uses the XsltArgumentList object. Specifically, you create an instance of the XsltArgumentList object, invoke its AddParam() method to add the BackGroundColor parameter, and finally pass the XsltArgumentList as an argument to the Transform() method of the XslCompiledTransform. With all these enhancements in place, pointing the browser to the URL of the Web page results in the following output wherein all the categories records are displayed with the Tan background color:
Invoking Extension Objects from an XSLT Stylesheet
In addition to allowing you to pass parameters, the XsltArgumentList class also provides you with the ability to associate a class with the namespace URI, using which you can call the methods of a class directly from a stylesheet. The object whose methods are invoked from the stylesheet is called an extension object. For the purposes of this example, let us create an extension object named DateTimeConverter to format the ModifiedDate value to the appropriate format. To this end, let us create the DateTimeConverter class with only one method named ToDateTimeFormat() that formats the input date value based on the supplied format string.using System;
public class DateTimeConverter
{
public DateTimeConverter()
{}
public string ToDateTimeFormat(string data, string format)
{
DateTime date = DateTime.Parse(data);
return date.ToString(format);
}
}
Place the DateTimeConverter class in the App_Code folder so that it can then be easily referred to from the ASP.NET page. To be able to invoke the extension object from the XSLT stylesheet, you need to do the following:
Declare an alias for the extension object namespace at the top of the XSLT file
Invoke the method of the extension object using the alias
Collapse









Invoking extension objects from an XSLT Style Sheet

















center










As you can see, the adjustments made to the stylesheet are minimal. To the xsl:stylesheet element, you add the attribute xmlns:DateTimeConverter="urn:DateTimeConverter". This is done to associate a namespace URI for our extension object. The following line of code creates the association.
Once you have the association between the object and the namespace URI in place, you can then easily invoke the methods of the extension object from the stylesheet as if it is part of the stylesheet.
The following line of code demonstrates this.
In the above line, you invoke the ToDateTimeFormat() method of the DateTimeConverter class, passing to it the ModifiedDate and the desired date format string.
Now that you have had a look at the changes to the style sheet, let us turn our focus to the code required to pass the extension object to the stylesheet so that it can invoke the methods of the extension object.
Collapse<%@ Page Language="C#" %>
<%@ Import Namespace="System.Data.SqlClient" %>
<%@ Import Namespace="System.Xml" %>
<%@ Import Namespace="System.Xml.Xsl" %>
<%@ Import Namespace="System.Xml.XPath" %>
<%@ Import Namespace="System.Web.Configuration" %>

Let us walk through the important lines of the code.
In this line, you create an instance of the BGColor class.DateTimeConverter converter = new DateTimeConverter();
After you create an instance of the object, the next step would be to add the instantiated object to the XsltArgumentList object.argsList.AddExtensionObject("urn:DateTimeConverter",converter);
Finally, you pass the instantiated object, along with the rest of the parameters, to the stylesheet, using the following line of code:transform.Transform(xpathDoc,argsList,Response.Output);
Executing the above code results in the following output:
As you can see from the above output, the ModifiedDate value is appropriately formatted.
Conclusion
In this article, you have seen the following:
How to transform an XML document using an XSLT stylesheet.
How to supply parameters to an XSLT stylesheet using the XsltArgumentList class.
How to invoke methods of an extension object from an XSLT stylesheet.
How to filter a set of nodes using an XPath expression.
Although the application we created was simple in functionality, it should provide a solid foundation for understanding how to create applications using XSLT related classes in the .NET Framework 2.0.

XSL Transformations in .NET 2.0

The core XSLT related classes are contained in the System.Xml.Xsl namespace, and are as follows:

XslCompiledTransform - Core class that acts as the XSLT processor in .NET Framework 2.0. Used to transform XML data into other structures such as HTML, text, or another XML.
XsltArgumentList - Allows you to pass a variable number of parameters and extension objects to an XSL style sheet.
XsltCompileException - This exception is thrown by the Load() method when an error occurs in the XSL style sheet.
XsltException - This exception is thrown if an exception occurs during the processing of an XSL style sheet.
Note that the XslTransform class used for XSL transformations in .NET Framework 1.x is now obsolete, and replaced by the new XslCompiledTransform class. In addition to better performance, the XslCompiledTransform also provides better support for the XSLT 1.0 specification. Starting from .NET Framework 2.0, the recommended approach to performing XSL transformations is through the XslCompiledTransform class. Because of the similarity in design to the XslTransform class, you can easily migrate your existing code to utilize the XslCompiledTransform class.

Before looking at the code sample, let us have a brief look at the important methods of the XslCompiledTransform class that will be required.

Load - This method has several overloads, and it provides for loading of an XSL stylesheet into an XslCompiledTransform object from any one of the following resources: a string that specifies the URL, from an XmlReader object, or from an XPathNavigator object, and so on.
Transform - Allows you to transform the XML data into a specified format using the stylesheet that is already loaded (using the Load method).
Implementation
Now that you have had an overview of the XSLT classes and the methods, let us start by looking at a simple XSL transformation example. For the purposes of this article, you will retrieve the data from AdventureWorks database in the form of XML data, and transform it using XSLT to render the data as HTML in the browser.

Simple XSL Transformation
In this example, you will create a simple ASP.NET page that retrieves categories data from the DB as an XML stream and transforms that into HTML so that it can be displayed in the browser. Before looking at the ASP.NET page, let us look at the XSL file named Category.xsl.

Collapse









Simple XSLT Transformation














center










The XSL file basically contains the logic to loop through all the elements contained in the Categories element. The code for the ASP.NET page is as follows:









In the Page_Load event of the Web form, you retrieve the data (in the form of XML) from the ProductSubcategory table, and then apply an external XSLT stylesheet (named Category.xsl) on the XML data, to emit HTML. You then write this HTML directly onto the client browser. This is accomplished by passing in the Response.Output object to the Transform() method. Note that in the above example, the XPathDocument class is used for loading the XML document, because this class is optimized to provide high-performance XML document processing. If you navigate to the page using the browser, you will see the output below.



Passing Parameters to an XSLT Stylesheet
Similar to the way you pass parameters to a method or a function, you can also pass parameters to an XSLT stylesheet. Passing a parameter to a stylesheet gives you the ability to initialize a globally scoped variable, which is defined as any that is a child of the element. The code shown in bold shows the lines of code where the parameter is declared and then used:

Collapse










Passing Parameters to an XSLT Style Sheet

















center










After the declaration of the BackGroundColor parameter, the code then uses the BackGroundColor parameter to specify the background color for the element in the table.


Although the value of BackGroundColor was hard-coded in the declaration using the <> element, ideally it should be passed from the calling ASP.NET page. To accomplish this, you leverage the XsltArgumentList class. Specifically, the AddParam() method of the XsltArgumentList provides this functionality. The XsltArgumentList class is a key class that enables you to create XSLT reusable and maintainable style sheets by providing a mechanism to pass parameters to an XSLT stylesheet.

To the AddParam() method, you supply a qualified name, the namespace URI, and a value. If the parameter value is not a String, Boolean, Number, NodeFragment, or NodeSet, it will be forced to a double or string. The ASP.NET calling page that passes parameters to the stylesheet is shown below:

Collapse
<%@ Page Language="C#" %>
<%@ Import Namespace="System.Data.SqlClient" %>
<%@ Import Namespace="System.Xml" %>
<%@ Import Namespace="System.Xml.Xsl" %>
<%@ Import Namespace="System.Xml.XPath" %>
<%@ Import Namespace="System.Web.Configuration" %>


The above code is very similar to the first example except for the difference that this example uses the XsltArgumentList object. Specifically, you create an instance of the XsltArgumentList object, invoke its AddParam() method to add the BackGroundColor parameter, and finally pass the XsltArgumentList as an argument to the Transform() method of the XslCompiledTransform. With all these enhancements in place, pointing the browser to the URL of the Web page results in the following output wherein all the categories records are displayed with the Tan background color:



Invoking Extension Objects from an XSLT Stylesheet
In addition to allowing you to pass parameters, the XsltArgumentList class also provides you with the ability to associate a class with the namespace URI, using which you can call the methods of a class directly from a stylesheet. The object whose methods are invoked from the stylesheet is called an extension object. For the purposes of this example, let us create an extension object named DateTimeConverter to format the ModifiedDate value to the appropriate format. To this end, let us create the DateTimeConverter class with only one method named ToDateTimeFormat() that formats the input date value based on the supplied format string.

using System;

public class DateTimeConverter
{
public DateTimeConverter()
{}

public string ToDateTimeFormat(string data, string format)
{
DateTime date = DateTime.Parse(data);
return date.ToString(format);
}
}
Place the DateTimeConverter class in the App_Code folder so that it can then be easily referred to from the ASP.NET page. To be able to invoke the extension object from the XSLT stylesheet, you need to do the following:

Declare an alias for the extension object namespace at the top of the XSLT file
Invoke the method of the extension object using the alias
Collapse










Invoking extension objects from an XSLT Style Sheet

















center










As you can see, the adjustments made to the stylesheet are minimal. To the xsl:stylesheet element, you add the attribute xmlns:DateTimeConverter="urn:DateTimeConverter". This is done to associate a namespace URI for our extension object. The following line of code creates the association.


Once you have the association between the object and the namespace URI in place, you can then easily invoke the methods of the extension object from the stylesheet as if it is part of the stylesheet.

The following line of code demonstrates this.


In the above line, you invoke the ToDateTimeFormat() method of the DateTimeConverter class, passing to it the ModifiedDate and the desired date format string.

Now that you have had a look at the changes to the style sheet, let us turn our focus to the code required to pass the extension object to the stylesheet so that it can invoke the methods of the extension object.

Collapse
<%@ Page Language="C#" %>
<%@ Import Namespace="System.Data.SqlClient" %>
<%@ Import Namespace="System.Xml" %>
<%@ Import Namespace="System.Xml.Xsl" %>
<%@ Import Namespace="System.Xml.XPath" %>
<%@ Import Namespace="System.Web.Configuration" %>


Let us walk through the important lines of the code.

In this line, you create an instance of the BGColor class.

DateTimeConverter converter = new DateTimeConverter();
After you create an instance of the object, the next step would be to add the instantiated object to the XsltArgumentList object.

argsList.AddExtensionObject("urn:DateTimeConverter",converter);
Finally, you pass the instantiated object, along with the rest of the parameters, to the stylesheet, using the following line of code:

transform.Transform(xpathDoc,argsList,Response.Output);
Executing the above code results in the following output:



As you can see from the above output, the ModifiedDate value is appropriately formatted.

Conclusion
In this article, you have seen the following:

How to transform an XML document using an XSLT stylesheet.
How to supply parameters to an XSLT stylesheet using the XsltArgumentList class.
How to invoke methods of an extension object from an XSLT stylesheet.
How to filter a set of nodes using an XPath expression.
Although the application we created was simple in functionality, it should provide a solid foundation for understanding how to create applications using XSLT related classes in the .NET Framework 2.0.

Implementing IHierarchy Support Into Your Custom Collections

Introduction
This quick tutorial will hit on the major features of the IHierarchicalDataSource provided by ASP.NET 2.0. Throughout I take a common set of data (a storefront listing of categories) in the form of a strongly typed generic list and entity and bind it together using the IHierarchy family of interfaces demonstrating how to turn any custom collection into a useful data binding tool.

Background
Displaying hierarchical data on the web is not a simple task, as you may already know if you have ever tried to bind a custom collection of hierarchical data to a standard ASP.NET TreeView control. No matter what the original shape of the data is, it is quite a pain to loop through and bind using the AddNode methods provided. You have to recursively look up the parent controls, ensure your data is sorted, etc. Overall it is a pretty big pain in the [Insert Bleep Here]! Hopefully after reviewing the following, you will find it much easier to extend your custom collections with this technology and remove all your nested data headaches!

Enjoy!

Using the code
I have tried to package this up as seamless as possible. Open'er up in Visual Studio 2005 and you should have a file path ASP.NET Web Site. I have one file for each class object (I guess that is the "team developer" in me) and a static method in the common class for quick sample data tucked nicely into a strongly typed generic list implementation.

Viewing the Default.aspx page should yield a tree view of a computer store product category TreeView demonstrating the code below.

On with the show...
To start with, we need a basic entity and collection, mine looks similar to this:

Collapse
using System;
using System.Collections.Generic;

public class Category {

private int _categoryId;
private int _parentId;
private string _name;

public int CategoryId {
get { return _categoryId; }
set { _categoryId = value; }
}

public int ParentId {
get { return _parentId; }
set { _parentId = value; }
}
public string Name {
get { return _name; }
set { _name = value; }
}

public Category(int categoryId, int parentId, string name) {
_categoryId = categoryId;
_parentId = parentId;
_name = name;
}
}

public class CategoryCollection : List {

public CategoryCollection()
: base() {
}
}


Implementing IHierarchyData on the Entity
In order to tell the CLR that your collection has hierarchical data, it in fact must be! Let's add that by adding the System.Web.UI namespace along with implementing the IHierarchyData interface and its required members as shown here:

Collapse
using System;
using System.Collections.Generic;
using System.Web.UI;

public class Category : IHierarchyData {
...

#region IHierarchyData Members

// Gets an enumeration object that represents all the child
// nodes of the current hierarchical node.
public IHierarchicalEnumerable GetChildren() {

// Call to the local cache for the data
CategoryCollection children = new CategoryCollection();

// Loop through your local data and find any children
foreach (Category category in Common.GetCategoryData()) {
if (category.ParentId == this.CategoryId) {
children.Add(category);
}
}

return children;
}

// Gets an IHierarchyData object that represents the parent node
// of the current hierarchical node.
public IHierarchyData GetParent() {

// Loop through your local data and report back with the parent
foreach (Category category in Common.GetCategoryData()) {
if (category.CategoryId == this.ParentId)
return category;
}

return null;

}

public bool HasChildren {
get {
CategoryCollection children = GetChildren() as CategoryCollection;
return children.Count > 0;
}
}

// Gets the hierarchical data node that the object represents.
public object Item {
get { return this; }
}

// Gets the hierarchical path of the node.
public string Path {
get { return this.CategoryId.ToString(); }
}

public string Type {
get { return this.GetType().ToString(); }
}

#endregion
}

The GetChildren() and GetParent() methods are where the magic really takes place. These two internal methods power the hierarchy definition and allow the controls to link them appropriately.

Implementing IHierarchicalEnumerable on the Collection
For the code immediately above to work, the method GetChildren() is counting on us handing back an implementation of IHierarchicalEnumerable.

Implementing this interface is a simple task of coding one method (GetHierarchyData()) that will ensure proper object typing within the collection as shown below:

public class CategoryCollection : List, IHierarchicalEnumerable {
...

#region IHierarchicalEnumerable Members

// Returns a hierarchical data item for the specified enumerated item.
public IHierarchyData GetHierarchyData(object enumeratedItem) {
return enumeratedItem as IHierarchyData;
}

#endregion
}


Finally... Some Output!
To see the results, simply create a new ASPX page and add a ASP:TreeView control to it. In code-behind, the following snippets will bind the results from your newly decorated collection to the tree view and organize it within the hierarchy you defined.

ASP.Net
----------------------------------------------------------


Code Behind
----------------------------------------------------------
protected void Page_Load(object sender, EventArgs e) {

if (!IsPostBack) {

// Local cache of category data
CategoryCollection collection = Common.GetRootCategories();

// Bind the data source to your collection
uxTreeView.DataSource = collection;
uxTreeView.DataBind();
}
}

Now that your collection and entity are all hyped-up on interfaces, you can use them again and again on hierarchy displaying controls natively.

Points of Interest
If anyone can answer the question as to why this is hidden away in the System.Web.UI namespace, I would love to hear it! I cannot imagine this having "web only" requirements, but I have not yet tried it in a Windows application.

In the code download, I have also included an implementation of IHierarchicalDataSource and HierarchicalDataSourceView for those of you who prefer to declaratively bind the data on the ASPX side with DataSource controls.

History

COM Concept : Containment


ntroduction
Reusability is the mantra for the success of any technology in the field of programming. C++ supports the reusability by providing the concept of inheritance. Inheritance is the way by which the subclass inherits the functionality from its base class (parent class). The subclass has the option to modify the functionality, which has been provided by the base class (overriding), or to continue with the same functionality as that of the base class. Inheritance has made the life of the programmer’s easier, but this has a problem associated with it. Implementation inheritance, which is supported by C++, creates a strong bonding or the contract between the base class and a subclass. Any changes in the base class can cause a drastic affect on the child class and may cause the clients of the child class to break. Implementation Inheritance is not an appropriate technology to create a reusable components, which could be used anywhere, at anytime, by anybody without worrying about the internal implementation of the component.

COM doesn’t supports the Implementation inheritance as it violates the motto of the COM technology i.e. to create the reusable components. COM does supports the Interface inheritance, in which the subclass inherits the interface of the base class and not the implementation. Interface inheritance protects the clients of a component from change. Implementation inheritance can be simulated in COM by using the concept of component containment. In COM, the reusability is achieved by using containment and aggregation. This article will be covering the Containment technique, in which the outer component uses the inner component, in detail. The Aggregation will be covered in a separate article

Containment
Everything in COM is related with the interfaces. Containment is also implemented at the interface level. The COM containment is same as the C++ containment, in which the outer component is a client of an inner component. The outer component has pointers to interfaces on the inner component. The inner component is not exposed directly to the client and hence only the IUnknown of the outer component will be exposed to the client. In Containment, the outer component forwards (delegates) the calls to the inner component.

There could be two scenarios in which the containment can be implemented. The first case is the outer component implements its own interfaces and uses the interfaces of the inner component. The second case could be that the outer component reimplements an interface supported by the inner component and forward the call to the interface of the inner component.



In Containment, the outer component is acting as a client and using the interface of the inner component. In implementing the containment, the inner component and client are unaware of the fact that they are being the part of the containment implementation. The outer component has to be modified to support the containment.

Sample code - explanation
This article will explore the first scenario to explain the containment technique. In this sample code, the outer component utilizes the functionality, which is being provided by an inner component. The outer component needs some modification to accommodate the inner component as a contained object. The client and an inner component won’t be affected and will be unaware of the fact that they are taking part in the containment implementation. This sample code will demonstrate that the client is unfamiliar with the fact that the outer component is using the services of an inner component.



The outer component i.e. CMath will have a new member variable m_pISqaure, which is a pointer to ISquare interface on the inner component.

// Code Snippet for CMath class.

class CMath : public IMath {
public:
// Implementing IUnknown Interface.

virtual HRESULT __stdcall QueryInterface(const IID& iid,void **ppv);
virtual ULONG __stdcall AddRef();
virtual ULONG __stdcall Release();

//Implementing IMath Interface.
virtual void _STDCALL SumSquare(int Val1,int Val2,int* pResult);

// Constructor
CMath();

// Destructor
~CMath();

// Pointer to ISquare interface on the inner component.

ISquare* m_pISquare;
private:
long m_cRef;
};
As this COM Server (ContainmentSample.dll) supports two COM Components i.e. CMath and CSquare, therefore DllGetClassObject should have a validation for these two ClassIDs.

// Code Snippet for DllGetClassObject.

// COM SCM creates a class object only when the request has come for
// CLSID_CMath and CLSID_CSquare. After creating the
// class object, the IClassFactory interface pointer on the
// class object is returned back to the client.

STDAPI DllGetClassObject(const CLSID & clsid,const IID& iid,void **ppv)
{
// This server supports two COM Components and hence
// validation is performed.

if((clsid == CLSID_CMath) || (clsid == CLSID_CSquare)) {
cout<<"The requested component is supported by "
"COM server (ContainmentSample.dll)" << endl;
}
else
{
return CLASS_E_CLASSNOTAVAILABLE;
}
CFactory *pFactory = new CFactory();
if (pFactory == NULL) {
return E_OUTOFMEMORY;
}
HRESULT hResult = pFactory->QueryInterface(iid,ppv);
static_cast<< IUnknown* >>(pFactory)->Release();
return hResult;
}
The CreateInstance for the outer component has to be modified to accommodate the creation of an inner component and storing the ISquare interface on the inner component in its member variable i.e. m_pISqaure. The outer component calls the CoCreateInstance with the CLSID parameter as CLSID_CSquare and queries for ISquare interface on the inner component (CSquare), and if the call is succeeds it stores the interface pointer in m_pISqaure.

Collapse
//Code Snippet for CreateInstance of Class Object.

//This snippet shows the part of the code which is
//executed during the creation of an outer
//component.

//This is executed when the client calls the CreateInstance,
//after getting the IClassFactory
//interface pointer on CMath's instance.
//The client gets the IClassFactory interface pointer by
//calling CoGetClassObject.

if ((iid == IID_IMath) || (iid == IID_IUnknown)) {
CMath* pMath = new CMath();
if(pMath == NULL) {
return E_OUTOFMEMORY;
}
// Here, the Outer Component initializes the inner component.
// The CoCreateInstance is called by
// the outer component during its creation and
// it queries for the ISquare interface on the inner
// component, and if the calls succeeds it stores the pointer
// in its variable m_pISqaure.

cout<<"Call to Create the Inner Component" << endl;

hResult = CoCreateInstance(CLSID_CSquare,NULL,CLSCTX_INPROC_SERVER,
IID_ISquare,(void**)&pMath->m_pISquare);

cout<<"CoCreateInstance for CSquare has been called"<< endl;

hResult = pMath->QueryInterface(iid,ppv);

if(SUCCEEDED(hResult)) {
pMath->Release();
}
}
Before executing the client application, the COM Server (ContainmentSample.dll) needs to be registered by regsvr32 utility. The next article will cover the aggregation technique, which is a specialized case of the containment

A Containment Sample

Introduction
Trying to learn about reuse mechanisms that can be applied in COM, I searched a lot on the net to find a very simple example on Containment, for starters. I found a lot of theory on the net, but not any simple example. Keeping in mind the starters, I will try to explain the steps involved in attaining Containment. I am not a good technical writer, but I will try to do my best.

Definition
Containment is a reuse mechanism. In this process of reuse mechanism, the outer component acts as a mediator between the client and the inner component, to delegate the calls. This mechanism makes sure that the inner component's interfaces are not exposed directly to the client.

We will build a ComplexCalculator component that exposes Add and Multiply functionalities through its interface. There is an existing component named “Calculator” that exposes an “Add” method through its interface, ISimpelMath. You can download the Calculator from the link above. I thought: why write code to get an existing functionality, “Add”? So, we will develop a new component, ComplexCalculator, using the existing component, Calculator.

Now, it’s enough for us to worry about “Multiply”.

Steps
Create a new ATL project, name it “ComplexCalculator”, and select the type as DLL.
Insert a new ATL object, name it as “ComplexMath”, and click OK.
Select the Class Wizard tab, right click on IComplexMath, and select “Add method”.
Method Name: Mul
Parameters: [in] long a, [in] long b, [out, retval] long* result
Add the following code:
STDMETHODIMP CComplexMath:: Mul (long a, long b, long *result)
{
*result = a * b;
return S_OK;
}
Select the Class Wizard tab, right click on CComplexMath, and select Implement Interface.
Click the “Add type library” button->Browse, select the Calculator.tlb, and click Open.
Open the ComplexCalculator.idl file and do the following changes:
Changes are indicated in bold letters.

library COMPLEXCALCULATORLib
{
importlib("stdole32.tlb");
importlib("stdole2.tlb");
import "Calculator.idl";
//import the Calculator’s IDL file.
//If not present in local dir, specify the path.
[
uuid(FB30F62F-4DF3-47CD-A67F-50E0CF7C7B67),
helpstring("ComplexMath Class")
]
coclass ComplexMath
{
[default] interface IComplexMath;
interface ISimpleMath;
//Add the interface name to the coclass
//so that it can be exposed to the client.
};
};
Open the ComplexMath.h file and add the following code:
The outerCOM (ComplexMath) creates an object of innerCOM (SimpleMath).

ISimpleMath* SimpleMathptr;

//Override the FinalConstruct to get the
//interface pointer of the Inner Component.
HRESULT FinalConstruct()
{
return CoCreateInstance(__uuidof(SimpleMath),NULL,
CLSCTX_INPROC_SERVER,
__uuidof(ISimpleMath),
(void**)&SimpleMathptr);
}
void FinalRelease()
{
SimpleMathptr->Release();
}
Change the Add method code in the ComplexMath.h as follows:
This is how the outerCOM (ComplexMath) delegates the calls to the innerCOM (SimpleMath).

STDMETHOD(Add)(LONG a, LONG b, LONG * result)
{
SimpleMathptr->Add(a,b,result);
return S_OK;
}
That’s it….

The outer component contains the inner component object. The user feels as if he is using the ComplexCalculator even when he queries for the SimpleMath interface.

Let's quickly build a client and make sure the containment relation works properly.

Client
Create a dialog based MFC application and place a button on the dialog. In the StdAfx.h, add the following:

#import "ComplexCalculator.tlb"
// If this is not present in the current dir, specify the path.
Add the following code to the OnButton event:

using namespace COMPLEXCALCULATORLib;
void CContainmentClientDlg::OnButton1()
{
CoInitialize(NULL);
CString str;
long res1;
IComplexMathPtr objComplex(__uuidof(ComplexMath));
//Use the smart
//pointer to get
//ComplexMath

res1=objComplex->Mul(10,20);
str.Format("Mul is=%d",res1);
AfxMessageBox(str);

ISimpleMathPtr objSimple;
objSimple=objComplex; //Use the assignment operator on the
//smart Pointer which will take care of
//query interface to SimpleMath interface.
long m = objSimple->Add(10,20);
str.Format("Add of 10,20 is=%d",m);
AfxMessageBox(str);
objComplex=NULL;
objSimple=NULL;

CoUninitialize();
}
Register the DLLs before you use the source code.


License