Dynamic class loading

Interface for dynamic class loading

The only way to register an embedded class with the Rice is the AddBuiltIn() member function which is a static member function of the RiceManager class described in the previous chapter.


public static void AddBuiltIn(string typename, PlainProtoTypeGetter pptg)


You can register an embedded class by calling this member function by passing the class name and a delegate of PlainProtoTypeGetter type.

In other words, dynamic class loading is a dynamic call of the AddBuiltIn() member function.


As an interface for dynamic class loading, Rice provides the IEmbedPrototype interface and the RegisterClasses() member function which is a static member function of the RiceManager class.


An application that uses the Rice can prepare its own interface, but by using a unified interface, you can reuse embedded classes between applications.

IEmbedPrototype interface

The IEmbedPrototype interface is an interface to be called when a dll file including an embedded class is dynamically loaded.

The IEmbedPrototype interface is shown below.


public interface IEmbedPrototype { void Embed(string path);}


The IEmbedPrototype interface is defined in rice.cs of the Rice source and has an Embed() member function which is the only member function.

The Embed() member function takes a string as an argument. This argument assumes that the absolute path of the dll file to be embedded will be passed.


As explained below, the RegisterClasses() member function searches for a class with the IEmbedPrototype interface in the dynamically loaded dll file and calls its Embed() member function.

In other words, dynamic class loading can be realized by defining a class with the IEmbedPrototype interface in the dll file and calling the AddBuiltIn() member function with that Embed() member function.


As an example, let's implement the IEmbedPrototype interface for the Rtemplate class.

RtemplateEmbedder is a class for dynamic loading. If you put this class in the same project as Rtemplate and build the project, a dynamically loadable dll file will be created.

1:

using Rice;

2:
3:

public class RtemplateEmbedder : IEmbedPrototype {

4:

public void Embed(string path) {

5:

RiceManager.AddBuiltIn(Rtemplate.TYPENAME, Rtemplate.InstanceGetter);

6:

}

7:

}

RegisterClasses() member function

The RegisterClasses() member function is a member function for searching dll files of all embedded classes in the specified directory and dynamically loading the class.

The RegisterClasses() member function takes a string as an argument. Please pass the absolute path of the appropriate directory to this argument.

If it finds a embedded class dll file, it calls the Embed() member function of the IEmbedPrototype interface.

The search is done recursively. In other words, not only the directory specified by the argument but also all its descendant directories are searched.

The implementation of the RegisterClasses() member function is shown below.

1:

//Batch registration of embedded classes existing in the specified directory.

2:

public static void RegisterClasses(string directoryPath) {

3:

DirectoryInfo dllsInfo = new DirectoryInfo(directoryPath);

4:

if(dllsInfo.Exists) {

5:

_recursiveRegistration(dllsInfo);

6:

}

7:

}

8:
9:

//Recursive search and incorporation of embedded class dll files.

10:

private static void _recursiveRegistration(DirectoryInfo currentDirectory) {

11:

foreach(FileInfo childFile in currentDirectory.GetFiles("Rtype.*.dll")) {

12:

Assembly asm = Assembly.LoadFrom(childFile.FullName);

13:

foreach(Type t in asm.GetTypes()) {

14:

IEmbedPrototype e = null;

15:

try {

16:

e = Activator.CreateInstance(t) as IEmbedPrototype;

17:

}

18:

catch {

19:

continue;

20:

}

21:

if(e != null)

22:

e.Embed(childFile.FullName);

23:

}

24:

}

25:

foreach(DirectoryInfo childDirectory in currentDirectory.GetDirectories()) {

26:

_recursiveRegistration(childDirectory);

27:

}

28:

}

Detecting of embedded class dll file is based on file name.

When loading an embedded class using the RegisterClasses() member function, file name of the embedded class dll file must match the file name pattern "Rtype.*.dll".

For example,


If it is a dll file for datetime class, "Rtype.Datetime.dll".

If it is a dll file for the regex (regular expression) class, "Rtype.Regex.dll".


Herewith, it ensures that only embedded class dll files are loaded properly, even if the embedded class dll file and other dll files are mixed.

Copyright © Rice All rights reserved.