.Net Runtime Library for Delphi
Import .Net Assemblies
Describes how to import .net assemblies and generates delphi classes from the types of the imported assemblies.
System_CAPS_note Note

Before you can use this utility to generate delphi classes from .Net assemblies, you must have Delphi Host Class Library and Delphi Framework Class Library installed.

Follow the steps below to import .Net Assemblies and generate Delphi Classes from the types of the Assemblies imported:
Step 1: Click on the add button  to add .Net Assembly files to the Assembly Names list. The assemblies can be removed by selecting the assemblies on the list and subsequently clicking on the remove button .
The right part of the screen above displays the properties of the assemblies to be imported.
The delphi unit name for the assembly can be changed from the property display section. For instance, the name of the above assembly on the list has been changed from System.Xml to SystemXmlUnit.
To load assemblies from the Global Assembly Cache (GAC), click on the GAC button and the GAC assembly form below will be shown.
Select the assemblies to import from the GAC assembly form above and click the Ok button to add the selected assemblies to the list.
Click the Next button and go to step 2.
Step 2: This screen allows you to specify which types and the members of the types of the assemblies you want to import. The members of the type includes the Constructors, Fields, Properties, Methods and Events. In the screen below, the XmlDocument type has been selected and atleast one member item has also been selected for each member of the type.  

You can change the class names of the assembly types by clicking on the Modify Class Name button. The screen below will be shown where you can change the default class names of the assembly types.

Click the Next button and go to step 3.

Step 3: This screen allows you to determine how the imported assemblies should be loaded by the host library at runtime. There are four load assembly options, namely: 

a.       Load from GAC using Qualified Assembly Name: Selecting this option allows the host library to load the assembly from the Global Assembly Cache using the qualified assembly name. Example:  System.Data, Version=, Culture=neutral, PublicKeyToken=b78a5c561856e089

b.      Load from GAC using Partial Assembly Name: Selecting this option allows the host library to load the assembly from the Global Assembly Cache using the partial name of the assembly. Considering the above example, instead of specifying the full qualified name, you can specify only the name of the assembly. Example: System.Data

c.       Load from File Location: Selecting this option allows the host library to load the assembly from the specified file location.

d.      Load from EXE location: Selecting this option allows the host library to load the assembly from the location of the Delphi executing file. You can copy your .net assembly files to the delphi executable file directory and select this option.


Click the Next button and go to step 4.

Step 4: This screen allows you to specify the directory where the generated Delphi files will be stored after import. You can also select the option(s) for importing the assembly types. These options are:

a.       Separate larger generated Delphi units into different units: Selecting this option allows the process to automatically separates the delphi unit to be generated into smaller units if the unit to be generated from the assembly types will be larger and contains volumnous lines of code making it difficult to debug in delphi.

b.      Optimize process: Selecting this option allows the process to perform a number of delphi code optimization such as excluding public field members of the selected types to be imported and prevent creating full class definition for types without any members.

c.       Search and include type references in other assemblies to be imported: Selecting this option allows the process to search for any dependencies in the list of assemblies to be imported and use the referenced type rather than specifying a default value or creating a class for the referenced type.

Click the Finish Button to start the process.

After the process is complete, atleast 2 files or delphi units will have been generated for each assembly file imported. These units are:

·       Constant Unit : This delphi unit contains the string constant variables of the assembly ID, the assembly load option path and the fullnames of the .net assembly types imported. This unit file name is the combination of the name of the class unit and Const.

The example below shows the content of the constant unit generated from the System.Xml assembly file.

unit SystemXmlUnitConst; interface const sC_SystemXmlUnit_Asm_ID = '4a01b83c-6007-406a-a205-5c348fdb2fdd'; sC_SystemXmlUnit_sC_AssemblyPath = 'System.Xml, Version=, Culture=neutral, PublicKeyToken=b77a5c561934e089'; sC_SysXml_XmlDocument = 'System.Xml.XmlDocument'; implementation end.



·      Class Unit(s) : Contains the types and members of the types imported from the .net assembly file which is represented as classes in this unit. More than one class unit can be generated if the option "Separate larger generated Delphi units into different units" is selected and the assembly file to be imported will result in a larger and voluminous lines of code in a single unit.

The example below shows the content of the Class Unit generated from the System.Xml assembly file.

unit SystemXmlUnit; {$WARN SYMBOL_PLATFORM OFF} {$WARN HIDING_MEMBER OFF} interface uses CNClrLib.Host, CNClrLib.Core, CNClrLib.Host.Utils, CNClrLib.Xml, CNClrLib.TypeNames, SystemXmlUnitConst; type { Forward Declarations } TXmlDocument = Class; { Event Handlers } TXmlNodeChangedEventHandler = procedure(sender: TClrBaseObject; e: _XmlNodeChangedEventArgs) of Object; { TXmlDocument } TXmlDocument = Class(TClrBaseObject) private FNodeChanged : TXmlNodeChangedEventHandler; procedure Set_InnerText(Value: String); function Get_InnerXml: String; procedure Set_InnerXml(Value: String); procedure Set_NodeChanged(Value : TXmlNodeChangedEventHandler); public constructor Create; procedure Load(filename: String); procedure Save(filename: String); property InnerText: String write Set_InnerText; property InnerXml: String read Get_InnerXml write Set_InnerXml; property NodeChanged: TXmlNodeChangedEventHandler read FNodeChanged write Set_NodeChanged; end; function GetSystemXmlUnitAssembly: TClrAssembly; implementation function GetSystemXmlUnitAssembly: TClrAssembly; begin Result := TClrAssembly.GetRegisterAssembly(sC_SystemXmlUnit_Asm_ID); end; { TXmlDocument } constructor TXmlDocument.Create; begin inherited Create(sC_SysXml_XmlDocument, nil) end; procedure TXmlDocument.Load(filename: String); begin InvokeMethod('Load', [S_CnClr_System_String], [filename]); end; procedure TXmlDocument.Save(filename: String); begin InvokeMethod('Save', [S_CnClr_System_String], [filename]); end; procedure TXmlDocument_NodeChangedHandler(sender: _ClrObject; e: _ClrEventArgs); stdcall; var evtObject: TXmlDocument; evtArg: _XmlNodeChangedEventArgs; begin evtObject := TXmlDocument(ClrHostManager.GetRegisteredEventObject(sender)); evtArg := CoXmlNodeChangedEventArgs.Wrap(e.EventArgs); if Assigned(evtObject) and Assigned(evtObject.FNodeChanged) then evtObject.FNodeChanged(evtObject, evtArg); end; procedure TXmlDocument.Set_NodeChanged(Value : TXmlNodeChangedEventHandler); var stdEvtHandler : TClrEventHandler; begin stdEvtHandler := TXmlDocument_NodeChangedHandler; if @Value <> Nil then RegisterEventCallBack('NodeChanged', @stdEvtHandler) else UnRegisterEventCallBack('NodeChanged', @stdEvtHandler); FNodeChanged := Value; end; procedure TXmlDocument.Set_InnerText(Value: String); begin SetPropertyValue('InnerText', Value); end; function TXmlDocument.Get_InnerXml: String; begin Result := GetPropertyValue('InnerXml'); end; procedure TXmlDocument.Set_InnerXml(Value: String); begin SetPropertyValue('InnerXml', Value); end; initialization TClrAssembly.RegisterAssembly(sC_SystemXmlUnit_Asm_ID, sC_SystemXmlUnit_sC_AssemblyPath, ltGACByFullName); end.



·       Enums Unit : This delphi unit contains the enumeration types defined in the imported assembly types. If the assemblies to be imported do not have any enumeration types, this unit will not be generated. This unit file name is the combination of the name of the class unit and Enums.