The code's documentation can be found in the download, but the usage documentation is below:
Aspectus uses Gestalt.Net
for configuration. This doesn't mean much, however it does mean that you must create a class that derives from Aspectus.Config.Configuration. This is your configuration class. In it
there are three properties that matter, AssemblyName, AssemblyDirectory, and AspectLocation. AssemblyName determines the name of the assembly used by the generated classes, AssemblyDirectory is used when saving the generated classes (if you choose to save
them to the drive), and AspectLocation is the assembly that contains your aspects/extensions. The AspectLocation must be overridden to let the system know which assembly to use. The download includes a set of demo extensions called AspectusExtensions. For
testing, you can include this in your main application and just point AspectLocation to AspectusExtensions.
In your application's startup you must also register this configuration class with Gestalt.Net. As such you will need to call the following function:
The assembly object can easily be determined by simply doing typeof(NameOfMyConfigClass).Assembly. Once it is registered, the system will be ready for use.
Creating an Aspect
An aspect is really nothing more than an extension that the system uses. These are the individual bits of code that you want to inject/hook into the system. All extensions derive from the Aspect class, which is found in Aspectus.BaseClasses. This class allows
the system to identify the item as an extension and set up the config class for it. The system uses
to locate and start up the aspects. Since it is using DotExtension, you should also know that all aspects/extensions must have a config class (these are very similar to the main config class as it
also uses Gestalt.Net). These can be used to pass information into the aspect from the outside, or left blank if you don't really need it. If you want to know more about these config classes, you can go to the DotExtension site linked to above and read
up in the config section.
Once you have the config class set up and a class that derives from Aspectus.BaseClasses.Aspect, you need to hook into the system. The main way that you will do this is through the Setup function in the Aspect class. This can be overridden and will be called
when an object is requested. You will then, most likely, hook into the system using the IEvents interface. All objects that are created by Aspectus are injected with an IEvents interface. This interface has three events, Starting, Ending, and Exception. Starting
is called at the beginning of a function call, ending is called at the end of a function call, and exception is called when an exception occurs during a function call. With the starting event, you'll be passed the parameter values for the function and
the function name. You can also set the return value, which will return that value for the function without running the base code. The ending event receives the parameter values, function name, and the return value that the base code wishes to return. You
can set your own return value at this point also. The exception event only receives the exception that was thrown (which will be rethrown by the code).
Using those events is usually enough for most extensions. In fact it usually is enough in about 99% of the extensions out there, however in some cases you may need to inject your own interfaces and IL. In those instances, there are a set of other functions
that can be overridden (namely the InterfacesUsing property as well as the SetupInterfaces, SetupStartMethod, SetupEndMethod, and SetupExceptionMethod functions). The HaterAideAspect in the AspectusExtensions project is an example of this approach. In it,
it shows how to use those functions to implement lazy loading for objects using the
(this is actually how it will be implemented in future releases and thus certain things like the config class are actually in the HaterAide project and not the extension's project).
For further help with creating an extension/aspect, please take a look at the enclosed examples.
Creating an Object
In order to actually get started creating an object, well, really all you have to do is call one function:
Note that in instances where you don't know the type at compile time, you can also call:
Note that the second one just returns an Object where as the first one returns a ClassIWantReturned. But calling one of those functions will automatically register the class and generate the sub class (which is done the first time, thus saving you time on subsequent
calls). However if you would prefer to register the classes earlier, you can always call:
This can be called during start up, thus speeding up the actual running of your app. Anyway, once the object is created, the aspects will hook into the sub class and automatically do their respective functions.