“Hello World” Example with AspectDNG


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

using System;

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

using System;

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

<?xml version="1.0" encoding="utf-8"?>
<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

<Advice xmlns="http://www.dotnetguru.org/AspectDNG">
    
<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:

// Decompiled by Salamander version 1.0.6
// 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

<WeaveLog>
  
<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
原文地址:https://www.cnblogs.com/teddyma/p/240364.html