NetReflector is a library which can be used to help implement the conversion of an object or set of objects to and from an XML representation.
This type of operation is particularly useful when developing applications with plug-in components, since the underlying executable does not need to know in advance which type(s) of object it will be supplied. (Typically, it will know that the object(s) in question will implement a specific interface, but even that is not essential).
A quick overview.
- NetReflector uses attributes to mark which class objects and properties within the object are serialized.
- Any object which you want to instantiate directly using NetReflector should be marked with the "ReflectorType" attribute. It should also have a default constructor (i.e. one that takes no parameters).
- Any property of the object which can be set by NetReflector should be marked with the "ReflectorProperty" attribute. The property must also possess a public set method.
- To create an object (or set of objects) from an XML representation, you use the NetReflector.Read method.
- To serialize an object (or set of objects) to XML, use the Netreflector.Write method.
Example:
- Open Visual Studio (or the development tool of your choice) and create a new console application. Call it NetReflectorSimpleDemo.
- Add a reference to the NetReflector library.
- Copy the following text into the main class file (Yes, I know having multiple classes in the same source file is not best practice, I just wanted to keep this as simple as possible. This code should work under .NET 1.1 or 2.0.):
using System;
using System.Configuration;
using Exortech.NetReflector;
namespace NetReflectorSimpleDemo {
public class EntryPoint {
[STAThread]
private static void Main(string[] args)
{
// Use NetReflector to instantiate the object which will actually
// do the work. All we need to know is that the object will have a
// "GetDetails" method which returns a String.
AppSettingsReader appSettings = new AppSettingsReader();
String settings = appSettings.GetValue("NetReflector", typeof (String)).ToString();
IPlugin worker = NetReflector.Read(settings) as IPlugin;
Console.Write(worker.GetDetails());
}
}
public interface IPlugin
{
String GetDetails();
}
[ReflectorType("PluginA")]
public class PluginOptionA : IPlugin
{
public String GetDetails()
{
return "This is plugin A.";
}
}
[ReflectorType("PluginB")]
public class PluginOptionB : IPlugin
{
[ReflectorProperty("Option", Required=false)]
public string option = "Default option string";
public String GetDetails()
{
return String.Format("This is plugin B. The option string is : {0}", option);
}
}
}
- Create an application configuration file and copy the following text into it:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<appSettings>
<add key="NetReflector" value="<PluginA />"/>
<!--
Alternate options include the following:
<add key="NetReflector" value="<PluginB />"/>
<add key="NetReflector" value="<PluginB Option='User specified option.' />"/>
-->
</appSettings>
</configuration>
- Build and run the application. If all is well, then the first time you run it you will see the message "This is plugin A".
- Now for the good part. Using Notepad, or a similar text editor modify the application configuration file (typically NetReflectorSimpleDemo.exe.config). Substitute one of the alternate options from the commented area for the original <add> element. Rerun the application, and you should find that the message is now different.
So what use is this?
What you have just done is demonstrated how a different implementation can be selected at runtime just by changing a configuration file. If that looks somewhat like the Strategy pattern, that's because it is!
In this simple example, all the possible strategies are encapsulated within the same assembly. This does not have to be the case! NetReflector will recognize items in any currently loaded assembly. This means that it is a relatively trivial task to supply new strategies after the initial product has shipped, or update existing ones, without changing the main application.
To keep the example simple, we have also not saved the configuration. There is nothing stopping you from providing a user interface in the application to manage the plugin(s), then store the updated configuration using the Write method.
New to this so just wanted to know