Return to Contents
6. “Hello World” Example with AspectDNG
In this chapter, let’s try to use AspectDNG to do an AOP example together.
Firstly, I define the base and aspect assemblies as below:
TestBaseClass.cs in BaseLib.dll
namespace BaseLib
{
/// <summary>
/// Summary description for TestBaseClass.
/// </summary>
public class TestBaseClass
{
public TestBaseClass()
{
}
public void MethodToBeDeleted()
{
}
public void MethodWarningToBeAdded()
{
}
public void MethodErrorToBeAdded()
{
}
public void MethodToTestInlineConstructorCall()
{
object obj = new TestBaseClass();
}
public void MethodToTestInlineMethod()
{
}
public void MethodToTestInlineMethodCall()
{
MethodToTestInlineMethod();
}
private string fieldToTestInlineField = "fieldToTestInlineField";
public void MethodToTestInlineFieldAccess()
{
string str = fieldToTestInlineField;
fieldToTestInlineField = "WriteFieldToTestInlineField";
}
public void MethodToTestAroundBody()
{
Console.Write("MethodToTestAroundBody");
}
public void MethodToTestAroundCall()
{
MethodToTestAroundBody();
}
}
}
TestAspectClass.cs in AspectLib.dll
namespace AspectLib
{
/// <summary>
/// Summary description for TestAspectClass.
/// </summary>
public class TestAspectClass
{
public TestAspectClass()
{
}
public void CodeToBeAddedAsInlineBeforeConstuctorCall()
{
Console.Write("CodeToBeAddedAsInlineBeforeConstuctorCall");
}
public void CodeToBeAddedAsInlineAfterConstuctorCall()
{
Console.Write("CodeToBeAddedAsInlineAfterConstuctorCall");
}
public void CodeToBeAddedAsInlineBeforeMethodCall()
{
Console.Write("CodeToBeAddedAsInlineBeforeMethodCall");
}
public void CodeToBeAddedAsInlineAfterMethodCall()
{
Console.Write("CodeToBeAddedAsInlineAfterMethodCall");
}
public void CodeToBeAddedAsInlineAtStart()
{
Console.Write("CodeToBeAddedAsInlineAtStart");
}
public void CodeToBeAddedAsInlineBeforeReturn()
{
Console.Write("CodeToBeAddedAsInlineBeforeReturn");
}
public void CodeToBeAddedAsInlineBeforeFieldReadAccess()
{
Console.Write("CodeToBeAddedAsInlineBeforeFieldReadAccess");
}
public void CodeToBeAddedAsInlineBeforeFieldWriteAccess()
{
Console.Write("CodeToBeAddedAsInlineBeforeFieldWriteAccess");
}
public void CodeToBeAddedAsInlineAfterFieldReadAccess()
{
Console.Write("CodeToBeAddedAsInlineAfterFieldReadAccess");
}
public void CodeToBeAddedAsInlineAfterFieldWriteAccess()
{
Console.Write("CodeToBeAddedAsInlineAfterFieldWriteAccess");
}
public void CodeToBeAddedAsAroundBody()
{
Console.Write("CodeToBeAddedAsAroundBody");
}
public void CodeToBeAddedAsAroundCall()
{
Console.Write("CodeToBeAddedAsAroundCall");
}
}
public class TestClassToBeInserted
{
}
}
The AspectDngConfig and Advice configuration are as below:
AspectDngConfig.xml
<AspectDngConfig xmlns="http://www.dotnetguru.org/AspectDNG"
debug="false"
logWarnings="true" logWarningsPath="Warnings.log"
logIlml="true" logIlmlPath="BaseLib.ilml.xml"
logWeaving="true" logWeavingPath="BaseLib.weaving.xml"
validateRules="true">
<BaseAssembly>BaseLib/bin/Debug/BaseLib.dll</BaseAssembly>
<AspectsAssembly>AspectLib/bin/Debug/AspectLib.dll</AspectsAssembly>
<AdviceFiles>
<AdviceFile>HelloAspectDngAdvice.xml</AdviceFile>
</AdviceFiles>
</AspectDngConfig>
HelloAspectDngAdvice.xml
<Delete
targetXPath="//Method[@name = 'MethodToBeDeleted']"/>
<Insert
aspectXPath="//Type[@name = 'TestClassToBeInserted']"
targetXPath="//Module"/>
<!--<Warning
targetXPath="//Method[@name = 'MethodWarningToBeAdded']"/>-->
<!--<Error
targetXPath="//Method[@name = 'MethodErrorToBeAdded']"/>-->
<!--<MakeSerializable
targetXPath="//Method[@name = 'TestBaseClass']"/>-->
<!--<SetBaseType
aspectXPath="//Type[@name = 'TestClassToBeInserted']"
targetXPath="//Type[@name = 'TestBaseClass']"/>-->
<!--<InlineBeforeConstructorCall
aspectXPath="//Method[@name = 'CodeToBeAddedAsInlineBeforeConstuctorCall']"
targetXPath="//TestBaseClass/Constructor"/>
<InlineAfterConstructorCall
aspectXPath="//Method[@name = 'CodeToBeAddedAsInlineAfterConstuctorCall']"
targetXPath="//TestBaseClass/Constructor"/>
<InlineBeforeMethodCall
aspectXPath="//Method[@name = 'CodeToBeAddedAsInlineBeforeMethodCall']"
targetXPath="//Method[@name = 'MethodToTestInlineMethod']"/>
<InlineAfterMethodCall
aspectXPath="//Method[@name = 'CodeToBeAddedAsInlineAfterMethodCall']"
targetXPath="//Method[@name = 'MethodToTestInlineMethod']"/>
<InlineBeforeFieldReadAccess
aspectXPath="//Method[@name = 'CodeToBeAddedAsInlineBeforeFieldReadAccess']"
targetXPath="//Field[@name = 'fieldToTestInlineField']"/>
<InlineAfterFieldReadAccess
aspectXPath="//Method[@name = 'CodeToBeAddedAsInlineAfterFieldReadAccess']"
targetXPath="//Field[@name = 'fieldToTestInlineField']"/>
<InlineBeforeFieldWriteAccess
aspectXPath="//Method[@name = 'CodeToBeAddedAsInlineBeforeFieldWriteAccess']"
targetXPath="//Field[@name = 'fieldToTestInlineField']"/>
<InlineAfterFieldWriteAccess
aspectXPath="//Method[@name = 'CodeToBeAddedAsInlineAfterFieldWriteAccess']"
targetXPath="//Field[@name = 'fieldToTestInlineField']"/>-->
<InlineAtStart
aspectXPath="//Method[@name = 'CodeToBeAddedAsInlineAtStart']"
targetXPath="//Method[@name = 'MethodToTestInlineMethod']"/>
<InlineBeforeReturn
aspectXPath="//Method[@name = 'CodeToBeAddedAsInlineBeforeReturn']"
targetXPath="//Method[@name = 'MethodToTestInlineMethod']"/>
<!--<AroundCall
aspectXPath="//Method[@name='CodeToBeAddedAsAroundCall']"
targetXPath="//Method[@name = 'MethodToTestAroundBody']"/>-->
<AroundBody
aspectXPath="//Method[@name='CodeToBeAddedAsAroundBody']"
targetXPath="//Method[@name = 'MethodToTestAroundBody']"/>
</Advice>
After execute the command:
aspectdng.exe –w AspectDngConfig.xml
BaseLib.dll is statically weaved and the source code (decompiled by Salamander) becomes below:
// Copyright 2002 Remotesoft Inc. All rights reserved.
// http://www.remotesoft.com/salamander
using System;
namespace BaseLib
{
public class TestBaseClass
{
private string fieldToTestInlineField = "fieldToTestInlineField";
public void MethodWarningToBeAdded()
{
}
public void MethodErrorToBeAdded()
{
}
public void MethodToTestInlineConstructorCall()
{
object local = new TestBaseClass();
}
public void MethodToTestInlineMethod()
{
Console.Write("CodeToBeAddedAsInlineAtStart");
Console.Write("CodeToBeAddedAsInlineBeforeReturn");
}
public void MethodToTestInlineMethodCall()
{
MethodToTestInlineMethod();
}
public void MethodToTestInlineFieldAccess()
{
string str = fieldToTestInlineField;
fieldToTestInlineField = "WriteFieldToTestInlineField";
}
public void MethodToTestAroundBody_9e793e7d-2628-4b5d-adf4-c089248c9ee7()
{
Console.Write("MethodToTestAroundBody");
}
public void MethodToTestAroundCall()
{
MethodToTestAroundBody();
}
public void MethodToTestAroundBody()
{
Console.Write("CodeToBeAddedAsAroundBody");
}
}
}
Conclusion
The uncommented operations defined in HelloAspectDngAdvice.xml are executed successfully. The commented code was also tested, but either failed or ignored by AspectDNG, seams they haven’t been supported correctly or not supported yet. And we can also check the weaving log file.
BaseLib.weaving.xml
<Weave name="Delete" targetXPath="//Method[@name = 'MethodToBeDeleted']">
<WeaveStep>
<TargetInfo>System.Void BaseLib.TestBaseClass::MethodToBeDeleted()</TargetInfo>
</WeaveStep>
</Weave>
<Weave name="Insert" aspectXPath="//Type[@name = 'TestClassToBeInserted']" targetXPath="//Module">
<WeaveStep>
<AspectInfo>AspectLib.TestClassToBeInserted</AspectInfo>
<TargetInfo>BaseLib.dll</TargetInfo>
</WeaveStep>
</Weave>
<Weave name="InlineAtStart" aspectXPath="//Method[@name = 'CodeToBeAddedAsInlineAtStart']" targetXPath="//Method[@name = 'MethodToTestInlineMethod']">
<WeaveStep>
<AspectInfo>System.Void AspectLib.TestAspectClass::CodeToBeAddedAsInlineAtStart()</AspectInfo>
<TargetInfo>System.Void BaseLib.TestBaseClass::MethodToTestInlineMethod()</TargetInfo>
</WeaveStep>
</Weave>
<Weave name="InlineBeforeReturn" aspectXPath="//Method[@name = 'CodeToBeAddedAsInlineBeforeReturn']" targetXPath="//Method[@name = 'MethodToTestInlineMethod']">
<WeaveStep>
<AspectInfo>System.Void AspectLib.TestAspectClass::CodeToBeAddedAsInlineBeforeReturn()</AspectInfo>
<TargetInfo>System.Void BaseLib.TestBaseClass::MethodToTestInlineMethod()</TargetInfo>
</WeaveStep>
</Weave>
<Weave name="AroundBody" aspectXPath="//Method[@name='CodeToBeAddedAsAroundBody']" targetXPath="//Method[@name = 'MethodToTestAroundBody']">
<WeaveStep>
<AspectInfo>System.Void AspectLib.TestAspectClass::CodeToBeAddedAsAroundBody()</AspectInfo>
<TargetInfo>System.Void BaseLib.TestBaseClass::MethodToTestAroundBody()</TargetInfo>
</WeaveStep>
</Weave>
</WeaveLog>
Source Code Download
HelloAspectDNG.zip