Category Archives: Patterns & Practices

How To : SAP Integration with .Net 4.0 (SAP Connection Manager) & SharePoint

This is a simple, C# class library project to connect .NET applications with SAP.

ppt_img[1]

 

This component internally implements SAP .NET Connector 3.0. The SAP .NET Connector is a development environment that enables communication between the Microsoft .NET platform and SAP systems.

This connector supports RFCs and Web services, and allows you to write different applications such as Web form, Windows form, or console applications in the Microsoft Visual Studio .NET.

With the SAP .NET Connector, you can use all common programming languages, such as Visual Basic. NET, C#, or Managed C++.

Features
Using the SAP .NET Connector you can:

Write .NET Windows and Web form applications that have access to SAP business objects (BAPIs).

Develop client applications for the SAP Server.

Write RFC server applications that run in a .NET environment and can be installed starting from the SAP system.

Following are the steps to configure this utility on your project

Download and extract the attached file and place it on your machine. This package contains 3 libraries:

SAPConnectionManager.dll
sapnco.dll
sapnco_utils.dll

Now go to your project and add the reference of all these four libraries. Sapnco.dll and sapnco_utils.dll are inbuilt libraries used by SAP .NET Connector. SAPConnectionManager.dll is the main component which provides the connection between .NET and SAP.

Once the above steps are complete, you need to make certain entries related to SAP server on your configuration file. Here are the sample entries that you have to maintain on your own project. You need to change only the values which are marked in Bold. Rest remains unchanged.

<appSettings>
<add key=”ServerHost” value=”127.0.0.1″/>
<add key=”SystemNumber” value=”00″/>
<add key=”User” value=”sample”/>
<add key=”Password” value=”pass”/>
<add key=”Client” value=”50″/>
<add key=”Language” value=”EN”/>
<add key=”PoolSize” value=”5″/>
<add key=”PeakConnectionsLimit” value=”10″/>
<add key=”IdleTimeout” value=”600″/>
</appSettings>

To test this component, create one windows application. Add the reference of sapnco.dll, sapnco_utils.dll, andSAPConnectionManager.dll on your project.

Paste the below code on your Form lode event

SAPSystemConnect sapCfg = new SAPSystemConnect();
RfcDestinationManager.RegisterDestinationConfiguration(sapCfg);
RfcDestination rfcDest = null;
rfcDest = RfcDestinationManager.GetDestination(“Dev”);

sap_integration_en_round[1]
That’s it. Now you are successfully connected with your SAP Server. Next you need to call SAP business objects (BAPIs) and extract the data and stored it in DataSet or list.

Demo Code available on request!!

Advertisements

How To : Use the Office 365 API Client Libraries (Javascript and .Net)

blog-office365

One of the cool things with today’s Office 365 API Tooling update is that you can now access the Office 365 APIs using libraries available for .NET and JavaScript.

 

\\8These libraries make it easier to interact with the REST APIs from the device or platform of your choice. And when I say platform of your choice, it really is! Office 365 API and the client libraries support the following project types in Visual Studio today:https://sharepointsamurai.wordpress.com/wp-admin/post.php?post=1625&action=edit&message=10

  1. NET Windows Store Apps
  2. .NET Windows Store Universal Apps
  3. Windows Forms Applications
  4. WPF Applications
  5. ASP.NET MVC Web Applications
  6. ASP.NET Web Forms Applications
  7. Xamarin Android and iOS Applications
  8. Multi-device Hybrid Apps

p.s: support for more projects coming on the way….

Few Things Before We Get Started

  • The authentication library is released as “alpha”.
    • If you don’t see something you want or if you think we missed addressing some scenarios/capabilities, let us know!
    • In this initial release of the authentication library, we focused on simplifying the getting started experience, especially for Office 365 services and not so much on the interoperability across other services (that support OAuth) but that’s something we can start looking for next updates to make it more generic.
  • The library is not meant to replace Active Directory Authentication Library (ADAL) but it is a wrapper over it (where it exists) which gives you a focused getting started experience.
    • However, If you want to opt out and go “DIY”, you still can.

Setting Up Authentication

The first step to accessing Office 365 APIs via the client library is to get authenticated with Office 365.

Once you configure the required Office 365 service and its permissions, the tool will add the required client libraries for authentication and the service into your project.

Lets quickly look at what authenticating your client looks like.

Getting Authenticated

Office 365 APIs use OAuth Common Consent Framework for authentication and authorization.

Below is the code to authenticate your .NET application:

Authenticator authenticator = new Authenticator();

AuthenticationInfo authInfo =
await authenticator.AuthenticateAsync(ExchangeResourceId);

Below is the JS code snippet used for authentication in Cordova projects:

var authContext = new O365Auth.Context();
authContext.getIdToken('https://outlook.office365.com/')
.then((function (token) {
    var client = new Exchange.Client('https://outlook.office365.com/ews/odata', 
                         token.getAccessTokenFn('https://outlook.office365.com'));
    client.me.calendar.events.getEvents().fetch()
        .then(function (events) {
            // get currentPage of events and logout
            var myevents = events.currentPage;
            authContext.logOut();
        }, function (reason) {
            // handle error
        });
}).bind(this), function (reason) {
    // handle error
});

Authenticator Class

The Authenticator class initializes the key stuff required for authentication:

1) Office 365 app client Id

2) Redirect URI

3) Authentication URI

You can find these settings in:

– For Web Applications – web.config

– For Windows Store Apps – App.xaml

– For Desktop Applications (Windows Forms & WPF) – AssemblyInfo.cs/.vb

– For Xamarin Applications – AssemblyInfo.cs

If you would like to provide these values at runtime and not from the config files, you can do so by using the alternate constructor:

image

To authenticate, you call the AuthenticateAsync method by passing the service’s resource Id:

AuthenticationInfo authInfo = await authenticator.AuthenticateAsync(ExchangeResourceId);

If you are using the discovery service, you can specify the capability instead of the resource Id:

AuthenticationInfo authInfo =
await authenticator.AuthenticateAsync("Mail", ServiceIdentifierKind.Capability);

The string to use for other services if you use discovery service: Calendar, Contacts and MyFiles

NOTE:

– For now, if you want to use the discovery service, you will also need to configure a SharePoint resource, either Sites or My Files. This is because the discovery service currently uses SharePoint resource Id.

– Active Directory Graph & Sites do not support discovery service yet

Depending on your client, the AuthenticateAsync will open the appropriate window for you to authenticate:

– For web applications, you will be redirected to login page to authenticate

– For Windows Store Apps, you will get dialog box to authenticate

– For desktop apps, you will get a dialog window to authenticate

image

AuthenticatorInfo Class

Once successfully authenticated, the method returns an AuthenticatorInfo object which helps you to get the required access token:

ExchangeClient client =
new ExchangeClient(new Uri(ExchangeServiceRoot), authInfo.GetAccessToken);

And also help you re-authenticate for a different resource when you create the service client.

AuthenticationInfo graphAuthInfo =
    await authInfo.ReauthenticateAsync("https://graph.windows.net/");

The library automatically handles token lifetime management by monitoring the expiration time of the access token and performing a refresh automatically.

Thats it! – Now you can make subsequent calls to the service to return the items you want!

Authentication Library

For .NET projects:

The library is available as a Nuget package. So, if you want to add it manually to your project without the tool, you could do so. However, you will have to manually register an app in the Azure Active Directory to authenticate against AAD.

Microsoft Office 365 Authentication Library for ASP.NET

Microsoft Office 365 Authentication Library for .NET (Android and iOS)

Microsoft Office 365 Authentication Library for ASP.NET

For Cordova projects:

You will need to use the Office 365 API tool which generates the aadgraph.js under the Scripts folder that handles authentication.

Windows 8.1 Updated Reources and Tools

With Windows 8.1 also come lots of updates to the tools and templates that you can use to create Windows Store apps. These updates can help cut down the work in your development and test cycles.

 

Get the updated tools described below at our Windows 8.1 page.

 w81_intro_2

New or updated in Windows 8.1

General updates

Area Description of update
Support for updating your Windows Store apps to Windows 8.1. Migrate your Windows 8 app to Windows 8.1. This may first require updating your app code for Windows 8.1.
Windows Store app templates We’ve updated all templates for Windows 8.1, and we’ve added a new Hub template too.
Azure Mobile Services and push notification wizards
  • The Services Manager makes it easy to connect your app to Azure Mobile Services or Microsoft Advertising.
  • The push notification wizard makes it easy to set up a Azure Mobile Service to send push notifications to your app.
App bundle support Now you can combine resource packages (like multiple scales, languages, or Microsoft Direct3D feature levels) into a single .appxbundle file for submission to the Windows Store. For your customers, this means that your app is only deployed with the resources they need for their device and locale.
App validation on a remote device The Create App Package Wizard in Microsoft Visual Studio 2013 now makes it easy to validate your app using Windows App Certification Kit 3.0 on a remote device (such as Windows RT PCs).
Create coded UI tests using XAML Write automated functional tests for testing Windows Store apps using XAML and the cross-hair tool.

Note  Touch interactions are now supported for controls.

New Visual Studio theme/ and Visual Design We’ve added a third theme, Blue, to the existing Light and Dark themes. The Blue theme offers a mid-range color scheme reminiscent of Microsoft Visual Studio 2010.

Also, based on user feedback, we’ve enhanced all themes with additional color and clarity in icons, revised icons, more contrast across the development environment , and clearer segmentation of regions within the environment.

 

Diagnostics

Area Description of update
Mixed-language debugging For Windows Store apps that use JavaScript and C++, the debugger now lets you set breakpoints in either language and provides a call stack with both JavaScript and C++ functions.
Managed app debugging The debugger now displays return values. You can use Edit and Continue in 64-bit managed apps. Exceptions that come from Windows Store apps preserve information about the error, even across language boundaries.
Asynchronous debugging improvements The call-stack window now includes the creation stack if you stop in an asynchronous method.
Native “Just My Code” For native code, the call stack simplifies debugging by displaying only the code that you’ve created.
DOM Explorer
  • The Cascading Style Sheets (CSS) editor supports improved editing, Microsoft IntelliSense, inline style support, shorthand, specificity, and notification of invalid properties.
  • The Computed and Styles panes have been enhanced.
  • The DOM Explorer supports search, editing as HTML, IntelliSense, and undo stacks.
JavaScript Console The console now supports object preview and visualization, new APIs, multiline function support, IntelliSense, evaluation of elements as objects or HTML, and legacy document modes.
JavaScript Memory Profiler
  • Dominators view shows memory allocation retained by each object.
  • The profiler notifies you of potential memory leaks caused by detached or disconnected DOM nodes.
JavaScript UI Responsiveness
  • The Details pane includes hyperlinks to event source locations, plus a chart showing the percentage of time that each child event contributed to the selected event’s overall duration.
  • You can now expand instances of Layout and Style calculation events to display the HTML elements that were affected by the operation.
XAML UI Responsiveness For C#/VB/C++ XAML-based Windows Store apps, the XAML UI Responsiveness tool allows you to diagnose performance issues related to app startup and page navigation, panning and scrolling, and input responsiveness in general.

 

JavaScript editor

Area Description of update
Completion of enclosing character pairs The editor automatically inserts the closing character when you type a left brace (“{“), parenthesis (“(“), bracket (“[“), single quotation mark (“`”), or (“””). A smart auto-format and indent of your source is also made as it auto-completes.
Editor navigation bar This new UI feature helps you identify and move through the important elements in your source code. New for JavaScript developers, the navigation bar will highlight important functions and objects in your source.
Deprecation notes in IntelliSense. If a Windows API element has been deprecated in Windows 8.1, IntelliSense tooltips identify it as “[deprecated]”.
Go To Definition for namespaces You can right-click a namespace you use in your code (such as WinJS.UI) and then click Go To Definition to be taken to the line where that namespace is defined.
Identifier highlighting Select an identifier (for example, a variable, parameter, or function name) in your source and any uses of that identifier will be highlighted in your source code.

 

C++ development

Area Description of update
Windows Store app development for Windows 8.1
  • Boxed types in value structs

    You can now define value types by using fields that can be null—for example, IBox<int>^ as opposed to int. This means that the fields can either have a value, or be equal to nullptr.

  • Richer exception information

    C++/CX supports the new Windows error model that enables the capture and propagation of rich exception information across the Application Binary Interface (ABI); this includes call stacks and custom message strings.

  • Object::ToString is now virtual

    You can now override ToString() in user-defined Windows Runtime ref types.

C++11 standard compliance Compiler support for ISO C++11 language features

  • Default template arguments for function templates
  • Delegating constructors
  • Explicit conversion operators
  • Initializer lists and uniform initialization
  • Raw string literals
  • Variadic templates

Updated Standard Template Library (STL) to use the latest C++11 features Improvements to C99 libraries

  • C99 functionality added to
  • Complex math functions in new header, <complex.h>
  • Integer type support in new header, ; includes format string support for “hh”
  • Support for variable-argument scanf forms in . C99 variants of vscanf, strtoll, vwscanf/wcstoll, and isblank/iswblank are implemented.
  • New conversion support for long long and long double in <stdlib.h>
C++ REST SDK Modern C++ implementation of Representational State Transfer (REST) services. For more info see C++ REST SDK (codename “Casablanca”).
C++ Azure Mobile Services SDK The shortest path to a connected C++ app with a Azure backend.
C++ AMP SxS CPU/GPU debugging (for WARP accelerator), enhanced texture support (mipmaps and new sampling modes), and improved diagnostics and exceptions.
IDE productivity features
  • Improved code formatting.
  • Brace completion.
  • Auto-generation of event handler code in C++/CX and C++/CLI.
  • Context-based member list filtering.
  • Parameter help scrolling.
  • Toggle header/code file.
  • Resizable C++ project-properties window.
  • Faster builds. Numerous optimizations and multi-core utilization make builds faster, especially for large projects. Incremental builds for C++ apps that have references to C++ WinMD are also much faster.
App performance
  • Pass vector type arguments by using the __vectorcall calling convention to use vector registers.
  • Reduction or elimination of CPU/GPU data transfer in C++ AMP.
  • Auto-vectorization improvements.
  • C++/CX optimizations in allocations and casting.
  • Performance tuning of C++ AMP runtime libraries.
  • New: PGO for Windows Store app development.
Build-time performance enhancements Compiler throughput improvements for highly parallel builds.

 

 

HTML design tools

Area Description of update
CSS animation The timeline editor helps you create CSS animations.
JavaScript behaviors Add JavaScript event listeners to any element without writing code. Choose from a list of supplied event handlers or create your own.
Custom font embedding Create a branded experience by using custom fonts for HTML text.
Data binding Set the data binding for any template.
Rules and guides Create custom guides.
Border radius Easy-to-use handles on each element help you create rounded corners and ellipses.
Searching and setting CSS properties The search box lets you set CSS property values directly and quickly.
Finding elements with CSS syntax The live DOM search now supports CSS syntax. For example, you can automatically select all elements with class “myclass” by searching for “.myclass”.

 

XAML design tools

Area Description of update
XAML editor improvements The XAML editor in Visual Studio 2013 includes IntelliSense for data bindings and resources, smart commenting, and Go To Definition.
Rulers and guides Create custom guides.
Better style editing support Edit styles and templates in the context of the document where they’re used, even if they’re actually defined in another, shared location.
Sample data support The data panel enhances sample data support in XAML projects for the Windows Store. This includes the ability to create sample data from JSON content. For an example of how to set this up, see the updated Windows Store app project templates for XAML.
View state authoring The device panel in Blend for Microsoft Visual Studio 2013 and Visual Studio 2013 supports updated view states properties and requirements to support variable minimum widths.

 

Windows App Certification Kit 3.0

Use the latest version of the Windows App Certification Kit to test the readiness of Windows Store apps for Windows 8 and Windows 8.1 before on-boarding, and for the Windows 7, Windows 8, and Windows 8.1 Windows Desktop App Certification.

We’ve also updated the Windows App Certification Kit to give you a smooth experience. For example, you can now run tests in parallel to save time, and you have more flexibility in selecting the tests you run.

New validation tests

As with previous releases of Windows, we’ve revised the kit content to include more validation, helping to make sure that Windows apps running on the latest update are well behaved. Here’s a high-level breakdown of the new tests.

Test Description
Direct3D additional check Validates apps for compliance with Direct3D requirements, and ensures that apps using C++ and XAML are calling a new Trim method upon their suspend callback.
Supported directory structure Ensures that apps don’t create a structure on disk that results in files longer than MAX_PATH (260 characters).
File extensions and protocols Limits the number of file extensions and protocols that an app can register.
Platform appropriate files Checks for packages that contain cross-architecture binaries.
Banned file check Checks apps for use of outdated or prerelease components known to have security vulnerabilities.
JavaScript background tasks Verifies that apps that use JavaScript have the proper close statement in the background task, so the app doesn’t consume battery power unnecessarily.
Framework dependency rules Ensures that apps are taking the right framework dependencies for Windows 8 and Windows 8.1.

 

Test reports

We’ve made a number of changes to the test report generated by the Windows App Certification Kit. These reports include new information, are easier to read, and provide more links to resources that can help you resolve issues. Significant additions and updates include:

  • Expanded error-message details.
  • Actionable info for supported and deprecated APIs.
  • Details about the configuration of the current test device.
  • A language toggle (if the report is localized).

For more information on how to use this kit, see Using the Windows App Certification Kit.

How To : Use the Microsoft Monitoring Agent to Monitor apps in deployment

You can locally monitor IIS-hosted ASP.NET web apps and SharePoint 2010 or 2013 applications for errors, performance issues, or other problems by using Microsoft Monitoring Agent. You can save diagnostic events from the agent to an IntelliTrace log (.iTrace) file. You can then open the log in Visual Studio Ultimate 2013 to debug problems with all the Visual Studio diagnostic tools.

If you use System Center 2012, use Microsoft Monitoring Agent with Operations Manager to get alerts about problems and create Team Foundation Server work items with links to the saved IntelliTrace logs. You can then assign these work items to others for further debugging.

See Integrating Operations Manager with Development Processes and Monitoring with Microsoft Monitoring Agent.

Before you start, check that you have the matching source and symbols for the built and deployed code. This helps you go directly to the application code when you start debugging and browsing diagnostic events in the IntelliTrace log. Set up your builds so that Visual Studio can automatically find and open the matching source for your deployed code.

  1. Set up Microsoft Monitoring Agent.
  2. Start monitoring your app.
  3. Save the recorded events.
Set up the standalone agent on your web server to perform local monitoring without changing your application. If you use System Center 2012, see Installing Microsoft Monitoring Agent.

Set up the standalone agent

  1. Make sure that:
  2. Download the free Microsoft Monitoring Agent, either the 32-bit version MMASetup-i386.exe or 64-bit version MMASetup-AMD64.exe, from the Microsoft Download Center to your web server.
  3. Run the downloaded executable to start the installation wizard.
  4. Create a secure directory on your web server to store the IntelliTrace logs, for example, C:\IntelliTraceLogs.

    Make sure that you create this directory before you start monitoring. To avoid slowing down your app, choose a location on a local high-speed disk that’s not very active.

     

    Security note Security Note
    IntelliTrace logs might contain personal and sensitive data. Restrict this directory to only those identities that must work with the files. Check your company’s privacy policies.
  5. To run detailed, function-level monitoring or to monitor SharePoint applications, give the application pool that hosts your web app or SharePoint application read and write permissions to the IntelliTrace log directory. How do I set up permissions for the application pool?
  1. On your web server, open a Windows PowerShell or Windows PowerShell ISE command prompt window as an administrator.

     

    Open Windows PowerShell as administrator 

  2. Run the Start-WebApplicationMonitoring command to start monitoring your app. This will restart all the web apps on your web server.

     

    Here’s the short syntax:

     

    Start-WebApplicationMonitoring “<appName>” <monitoringMode> “<outputPath>” <UInt32> “<collectionPlanPathAndFileName>”

     

    Here’s an example that uses just the web app name and lightweight Monitor mode:

     

    PS C:\>Start-WebApplicationMonitoring “Fabrikam\FabrikamFiber.Web” Monitor “C:\IntelliTraceLogs”

     

    Here’s an example that uses the IIS path and lightweight Monitor mode:

     

    PS C:\>Start-WebApplicationMonitoring “IIS:\sites\Fabrikam\FabrikamFiber.Web” Monitor “C:\IntelliTraceLogs”

     

    After you start monitoring, you might see the Microsoft Monitoring Agent pause while your apps restart.

     

    Start monitoring with MMA confirmation 

    “<appName>” Specify the path to the web site and web app name in IIS. You can also include the IIS path, if you prefer.

     

    “<IISWebsiteName>\<IISWebAppName>”

    -or-

    “IIS:\sites \<IISWebsiteName>\<IISWebAppName>”

     

    You can find this path in IIS Manager. For example:

     

    Path to IIS web site and web app 

    You can also use the Get-WebSite and Get WebApplication commands.

    <monitoringMode> Specify the monitoring mode:

     

    • Monitor: Record minimal details about exception events and performance events. This mode uses the default collection plan.
    • Trace: Record function-level details or monitor SharePoint 2010 and SharePoint 2013 applications by using the specified collection plan. This mode might make your app run more slowly.

       

       

      This example records events for a SharePoint app hosted on a SharePoint site:

       

      Start-WebApplicationMonitoring “FabrikamSharePointSite\FabrikamSharePointApp” Trace “C:\Program Files\Microsoft Monitoring Agent\Agent\IntelliTraceCollector\collection_plan.ASP.NET.default.xml” “C:\IntelliTraceLogs”

       

    • Custom: Record custom details by using specified custom collection plan. You’ll have to restart monitoring if you edit the collection plan after monitoring has already started.
    “<outputPath>” Specify the full directory path to store the IntelliTrace logs. Make sure that you create this directory before you start monitoring.
    <UInt32> Specify the maximum size for the IntelliTrace log. The default maximum size of the IntelliTrace log is 250 MB.

    When the log reaches this limit, the agent overwrites the earliest entries to make space for more entries. To change this limit, use the -MaximumFileSizeInMegabytes option or edit the MaximumLogFileSize attribute in the collection plan.

    “<collectionPlanPathAndFileName>” Specify the full path or relative path and the file name of the collection plan. This plan is an .xml file that configures settings for the agent.

    These plans are included with the agent and work with web apps and SharePoint applications:

    • collection_plan.ASP.NET.default.xml

      Collects only events, such as exceptions, performance events, database calls, and Web server requests.

    • collection_plan.ASP.NET.trace.xml

      Collects function-level calls plus all the data in default collection plan. This plan is good for detailed analysis but might slow down your app.

     

    You can find localized versions of these plans in the agent’s subfolders. You can also customize these plans or create your own plans to avoid slowing down your app. Put any custom plans in the same secure location as the agent.

     

    How else can I get the most data without slowing down my app?

     

    For the more information about the full syntax and other examples, run the get-help Start-WebApplicationMonitoring –detailed command or the get-help Start-WebApplicationMonitoring –examples command.

  3. To check the status of all monitored web apps, run the Get-WebApplicationMonitoringStatus command.

Aspect-Oriented Programming with the RealProxy Class

A well-architected application has separate layers so different concerns don’t interact more than needed. Imagine you’re designing a loosely coupled and maintainable application, but in the middle of the development, you see some requirements that might not fit well in the architecture, such as:

  • The application must have an authentication system, used before any query or update.
  • The data must be validated before it’s written to the database.
  • The application must have auditing and logging for sensible operations.
  • The application must maintain a debugging log to check if operations are OK.
  • Some operations must have their performance measured to see if they’re in the desired range.

Any of these requirements need a lot of work and, more than that, code duplication. You have to add the same code in many parts of the system, which goes against the “don’t repeat yourself” (DRY) principle and makes maintenance more difficult. Any requirement change causes a massive change in the program.When I have to add something like that in my applications, I think, “Why can’t the compiler add this repeated code in multiple places for me?” or, “I wish I had some option to ‘Add logging to this method.’”

The good news is that something like that does exist: aspect-oriented programming (AOP). It separates general code from aspects that cross the boundaries of an object or a layer. For example, the application log isn’t tied to any application layer. It applies to the whole program and should be present everywhere. That’s called a crosscutting concern.

AOP is, according to Wikipedia, “a programming paradigm that aims to increase modularity by allowing the separation of crosscutting concerns.” It deals with functionality that occurs in multiple parts of the system and separates it from the core of the application, thus improving separation of concerns while avoiding duplication of code and coupling.

In this article, I’ll explain the basics of AOP and then detail how to make it easier by using a dynamic proxy via the Microsoft .NET Framework class RealProxy.

Implementing AOP 

The biggest advantage of AOP is that you only have to worry about the aspect in one place, programming it once and applying it in all the places where needed.There are many uses for AOP, such as:

  • Implementing logging in your application.
  • Using authentication before an operation (such as allowing some operations only for authenticated users).
  • Implementing validation or notification for property setters (calling the PropertyChanged event when a property has been changed for classes that implement the INotifyPropertyChanged interface).
  • Changing the behavior of some methods.

As you can see, AOP has many uses, but you must wield it with care. It will keep some code out of your sight, but it’s still there, running in every call where the aspect is present. It can have bugs and severely impact the performance of the application. A subtle bug in the aspect might cost you many debugging hours. If your aspect isn’t used in many places, sometimes it’s better to add it directly to the code.

AOP implementations use some common techniques:

  • Adding source code using a pre-processor, such as the one in C++.
  • Using a post-processor to add instructions on the compiled binary code.
  • Using a special compiler that adds the code while compiling.
  • Using a code interceptor at run time that intercepts execution and adds the desired code.

In the .NET Framework, the most commonly used of these techniques are post-processing and code interception. The former is the technique used by PostSharp (postsharp.net ) and the latter is used by dependency injection (DI) containers such as Castle DynamicProxy (bit.ly/JzE631 ) and Unity (unity.codeplex.com ). These tools usually use a design pattern named Decorator or Proxy to perform the code interception.

The Decorator Design Pattern 

The Decorator design pattern solves a common problem: You have a class and want to add some functionality to it. You have several options for that:

  • You could add the new functionality to the class directly. However, that gives the class another responsibility and hurts the “single responsibility” principle.
  • You could create a new class that executes this functionality and call it from the old class. This brings a new problem: What if you also want to use the class without the new functionality?
  • You could inherit a new class and add the new functionality, but that may result in many new classes. For example, let’s say you have a repository class for create, read, update and delete (CRUD) database operations and you want to add auditing. Later, you want to add data validation to be sure the data is being updated correctly. After that, you might also want to authenticate the access to ensure that only authorized users can access the classes. These are big issues: You could have some classes that implement all three aspects, and some that implement only two of them or even only one. How many classes would you end up having?
  • You can “decorate” the class with the aspect, creating a new class that uses the aspect and then calls the old one. That way, if you need one aspect, you decorate it once. For two aspects, you decorate it twice and so on. Let’s say you order a toy (as we’re all geeks, an Xbox or a smartphone is OK). It needs a package for display in the store and for protection. Then, you order it with gift wrap, the second decoration, to embellish the box with tapes, stripes, cards and gift paper. The store sends the toy with a third package, a box with Styrofoam balls for protection. You have three decorations, each one with a different functionality, and each one independent from one another. You can buy your toy with no gift packaging, pick it up at the store without the external box or even buy it with no box (with a special discount!). You can have your toy with any combination of the decorations, but they don’t change its basic functionality.

Now that you know about the Decorator pattern, I’ll show how to implement it in C#.

First, create an interface IRepository<T>:

  1. public interface IRepository<T>
  2.   void Add(T entity);
  3.   void Delete(T entity);
  4.   void Update(T entity);
  5.   IEnumerable GetAll();
  6.   T GetById(int id);

Implement it with the Repository<T> class, shown in Figure 1.

Figure 1 The Repository<T> Class

  1. public class Repository<T> : IRepository<T>
  2.   public void Add(T entity)
  3.     Console.WriteLine(“Adding {0}”, entity);
  4.   public void Delete(T entity)
  5.     Console.WriteLine(“Deleting {0}”, entity);
  6.   public void Update(T entity)
  7.     Console.WriteLine(“Updating {0}”, entity);
  8.   public IEnumerable GetAll()
  9.     Console.WriteLine(“Getting entities”);
  10.     return null;
  11.   public T GetById(int id)
  12.     Console.WriteLine(“Getting entity {0}”, id);
  13.     return default(T);

Use the Repository<T> class to add, update, delete and retrieve the elements of the Customer class:

  1. public class Customer
  2.   public int Id { get; set; }
  3.   public string Name { get; set; }
  4.   public string Address { get; set; }

The program could look something like Figure 2.

Figure 2 The Main Program, with No Logging

  1. static void Main(string[] args)
  2.   Console.WriteLine(“***\r\n Begin program – no logging\r\n”);
  3.   IRepository customerRepository =
  4.     new Repository<Customer>();
  5.   var customer = new Customer
  6.     Id = 1,
  7.     Name = “Customer 1”,
  8.     Address = “Address 1”
  9.   customerRepository.Add(customer);
  10.   customerRepository.Update(customer);
  11.   customerRepository.Delete(customer);
  12.   Console.WriteLine(“\r\nEnd program – no logging\r\n***”);
  13.   Console.ReadLine();

When you run this code, you’ll see something like Figure 3.

Output of the Program with No Logging

Figure 3 Output of the Program with No Logging

Imagine your boss asks you to add logging to this class. You can create a new class that will decorate IRepository<T>. It receives the class to build and implements the same interface, as shown in Figure 4.

Figure 4 The Logger Repository

  1. public class LoggerRepository<T> : IRepository<T>
  2.   private readonly IRepository _decorated;
  3.   public LoggerRepository(IRepository decorated)
  4.     _decorated = decorated;
  5.   private void Log(string msg, object arg = null)
  6.     Console.ForegroundColor = ConsoleColor.Red;
  7.     Console.WriteLine(msg, arg);
  8.     Console.ResetColor();
  9.   public void Add(T entity)
  10.     Log(“In decorator – Before Adding {0}”, entity);
  11.     _decorated.Add(entity);
  12.     Log(“In decorator – After Adding {0}”, entity);
  13.   public void Delete(T entity)
  14.     Log(“In decorator – Before Deleting {0}”, entity);
  15.     _decorated.Delete(entity);
  16.     Log(“In decorator – After Deleting {0}”, entity);
  17.   public void Update(T entity)
  18.     Log(“In decorator – Before Updating {0}”, entity);
  19.     _decorated.Update(entity);
  20.     Log(“In decorator – After Updating {0}”, entity);
  21.   public IEnumerable GetAll()
  22.     Log(“In decorator – Before Getting Entities”);
  23.     var result = _decorated.GetAll();
  24.     Log(“In decorator – After Getting Entities”);
  25.     return result;
  26.   public T GetById(int id)
  27.     Log(“In decorator – Before Getting Entity {0}”, id);
  28.     var result = _decorated.GetById(id);
  29.     Log(“In decorator – After Getting Entity {0}”, id);
  30.     return result;

This new class wraps the methods for the decorated class and adds the logging feature. You must change the code a little to call the logging class, as shown inFigure 5.

Figure 5 The Main Program Using The Logger Repository

  1. static void Main(string[] args)
  2.   Console.WriteLine(“***\r\n Begin program – logging with decorator\r\n”);
  3.   // IRepository customerRepository =
  4.   //   new Repository<Customer>();
  5.   IRepository customerRepository =
  6.     new LoggerRepository<Customer>(new Repository<Customer>());
  7.   var customer = new Customer
  8.     Id = 1,
  9.     Name = “Customer 1”,
  10.     Address = “Address 1”
  11.   customerRepository.Add(customer);
  12.   customerRepository.Update(customer);
  13.   customerRepository.Delete(customer);
  14.   Console.WriteLine(“\r\nEnd program – logging with decorator\r\n***”);
  15.   Console.ReadLine();

You simply create the new class, passing an instance of the old class as a parameter for its constructor. When you execute the program, you can see it has the logging, as shown in Figure 6.

Execution of the Logging Program with a Decorator

Figure 6 Execution of the Logging Program with a Decorator

You might be thinking: “OK, the idea is good, but it’s a lot of work: I have to implement all the classes and add the aspect to all the methods. That will be difficult to maintain. Is there another way to do it?” With the .NET Framework, you can use reflection to get all methods and execute them. The base class library (BCL) even has the RealProxy class (bit.ly/18MfxWo ) that does the implementation for you.

Creating a Dynamic Proxy with RealProxy 

The RealProxy class gives you basic functionality for proxies. It’s an abstract class that must be inherited by overriding its Invoke method and adding new functionality. This class is in the namespace System.Runtime.Remoting.Proxies.To create a dynamic proxy, you use code similar to Figure 7.

Figure 7 The Dynamic Proxy Class

  1. class DynamicProxy : RealProxy
  2.   private readonly T _decorated;
  3.   public DynamicProxy(T decorated)
  4.     : base(typeof(T))
  5.     _decorated = decorated;
  6.   private void Log(string msg, object arg = null)
  7.     Console.ForegroundColor = ConsoleColor.Red;
  8.     Console.WriteLine(msg, arg);
  9.     Console.ResetColor();
  10.   public override IMessage Invoke(IMessage msg)
  11.     var methodCall = msg as IMethodCallMessage;
  12.     var methodInfo = methodCall.MethodBase as MethodInfo;
  13.     Log(“In Dynamic Proxy – Before executing ‘{0}'”,
  14.       methodCall.MethodName);
  15.       var result = methodInfo.Invoke(_decorated, methodCall.InArgs);
  16.       Log(“In Dynamic Proxy – After executing ‘{0}’ “,
  17.         methodCall.MethodName);
  18.       return new ReturnMessage(result, null, 0,
  19.         methodCall.LogicalCallContext, methodCall);
  20.     catch (Exception e)
  21.      Log(string.Format(
  22.        “In Dynamic Proxy- Exception {0} executing ‘{1}'”, e),
  23.        methodCall.MethodName);
  24.      return new ReturnMessage(e, methodCall);

In the constructor of the class, you must call the constructor of the base class, passing the type of the class to be decorated. Then you must override the Invoke method that receives an IMessage parameter. It contains a dictionary with all the parameters passed for the method. The IMessage parameter is typecast to an IMethodCallMessage, so you can extract the parameter MethodBase (which has the MethodInfo type).

The next steps are to add the aspect you want before calling the method, call the original method with methodInfo.Invoke and then add the aspect after the call.

You can’t call your proxy directly, because DynamicProxy<T> isn’t an IRepository<Customer>. That means you can’t call it like this:

  1. IRepository<Customer> customerRepository =
  2.   new DynamicProxy<IRepository<Customer>>(
  3.   new Repository<Customer>());

To use the decorated repository, you must use the GetTransparentProxy method, which will return an instance of IRepository. Every method of this instance that’s called will go through the proxy’s Invoke method. To ease this process, you can create a Factory class to create the proxy and return the instance for the repository:

  1. public class RepositoryFactory
  2.   public static IRepository<T> Create<T>()
  3.     var repository = new Repository<T>();
  4.     var dynamicProxy = new DynamicProxy<irepository>(repository);
  5.     return dynamicProxy.GetTransparentProxy() as IRepository;

That way, the main program will be similar to Figure 8.

Figure 8 The Main Program with a Dynamic Proxy

  1. static void Main(string[] args)
  2.   Console.WriteLine(“***\r\n Begin program – logging with dynamic proxy\r\n”);
  3.   // IRepository<Customer> customerRepository =
  4.   //   new Repository<Customer>();
  5.   // IRepository<Customer> customerRepository =
  6.   //   new LoggerRepository<Customer>(new Repository<Customer>());
  7.   IRepository<Customer> customerRepository =
  8.     RepositoryFactory.Create<Customer>();
  9.   var customer = new Customer
  10.     Id = 1,
  11.     Name = “Customer 1”,
  12.     Address = “Address 1”
  13.   customerRepository.Add(customer);
  14.   customerRepository.Update(customer);
  15.   customerRepository.Delete(customer);
  16.   Console.WriteLine(“\r\nEnd program – logging with dynamic proxy\r\n***”);
  17.   Console.ReadLine();

When you execute this program, you get a similar result as before, as shown inFigure 9.

Program Execution with Dynamic Proxy

Figure 9 Program Execution with Dynamic Proxy

As you can see, you’ve created a dynamic proxy that allows adding aspects to the code, with no need to repeat it. If you wanted to add a new aspect, you’d only need to create a new class, inherit from RealProxy and use it to decorate the first proxy.

If your boss comes back to you and asks you to add authorization to the code, so only administrators can access the repository, you could create a new proxy as shown in Figure 10.

Figure 10 An Authentication Proxy

  1. class AuthenticationProxy : RealProxy
  2.   private readonly T _decorated;
  3.   public AuthenticationProxy(T decorated)
  4.     : base(typeof(T))
  5.     _decorated = decorated;
  6.   private void Log(string msg, object arg = null)
  7.     Console.ForegroundColor = ConsoleColor.Green;
  8.     Console.WriteLine(msg, arg);
  9.     Console.ResetColor();
  10.   public override IMessage Invoke(IMessage msg)
  11.     var methodCall = msg as IMethodCallMessage;
  12.     var methodInfo = methodCall.MethodBase as MethodInfo;
  13.     if (Thread.CurrentPrincipal.IsInRole(“ADMIN”))
  14.         Log(“User authenticated – You can execute ‘{0}’ “,
  15.           methodCall.MethodName);
  16.         var result = methodInfo.Invoke(_decorated, methodCall.InArgs);
  17.         return new ReturnMessage(result, null, 0,
  18.           methodCall.LogicalCallContext, methodCall);
  19.       catch (Exception e)
  20.         Log(string.Format(
  21.           “User authenticated – Exception {0} executing ‘{1}'”, e),
  22.           methodCall.MethodName);
  23.         return new ReturnMessage(e, methodCall);
  24.     Log(“User not authenticated – You can’t execute ‘{0}’ “,
  25.       methodCall.MethodName);
  26.     return new ReturnMessage(null, null, 0,
  27.       methodCall.LogicalCallContext, methodCall);

The repository factory must be changed to call both proxies, as shown in Figure 11.

Figure 11 The Repository Factory Decorated by Two Proxies

  1. public class RepositoryFactory
  2.   public static IRepository<T> Create<T>()
  3.     var repository = new Repository<T>();
  4.     var decoratedRepository =
  5.       (IRepository<T>)new DynamicProxy<IRepository<T>>(
  6.       repository).GetTransparentProxy();
  7.     // Create a dynamic proxy for the class already decorated
  8.     decoratedRepository =
  9.       (IRepository<T>)new AuthenticationProxy<IRepository<T>>(
  10.       decoratedRepository).GetTransparentProxy();
  11.     return decoratedRepository;

When you change the main program to Figure 12 and run it, you’ll get the output shown in Figure 13.

Figure 12 The Main Program Calling the Repository with Two Users

  1. static void Main(string[] args)
  2.   Console.WriteLine(
  3.     “***\r\n Begin program – logging and authentication\r\n”);
  4.   Console.WriteLine(“\r\nRunning as admin”);
  5.   Thread.CurrentPrincipal =
  6.     new GenericPrincipal(new GenericIdentity(“Administrator”),
  7.     new[] { “ADMIN” });
  8.   IRepository<Customer> customerRepository =
  9.     RepositoryFactory.Create<Customer>();
  10.   var customer = new Customer
  11.     Id = 1,
  12.     Name = “Customer 1”,
  13.     Address = “Address 1”
  14.   customerRepository.Add(customer);
  15.   customerRepository.Update(customer);
  16.   customerRepository.Delete(customer);
  17.   Console.WriteLine(“\r\nRunning as user”);
  18.   Thread.CurrentPrincipal =
  19.     new GenericPrincipal(new GenericIdentity(“NormalUser”),
  20.     new string[] { });
  21.   customerRepository.Add(customer);
  22.   customerRepository.Update(customer);
  23.   customerRepository.Delete(customer);
  24.   Console.WriteLine(
  25.     “\r\nEnd program – logging and authentication\r\n***”);
  26.   Console.ReadLine();
Output of the Program Using Two Proxies

Figure 13 Output of the Program Using Two Proxies

The program executes the repository methods twice. The first time, it runs as an admin user and the methods are called. The second time, it runs as a normal user and the methods are skipped.

That’s much easier, isn’t it? Note that the factory returns an instance of IRepository<T>, so the program doesn’t know if it’s using the decorated version.This respects the Liskov Substitution Principle, which says that if S is a subtype of T, then objects of type T may be replaced with objects of type S. In this case, by using an IRepository interface, you could use any class that implements this interface with no change in the program.

Filtering Functions 

Until now, there was no filtering in the functions; the aspect is applied to every class method that’s called. Often this isn’t the desired behavior. For example, you might not want to log the retrieval methods (GetAll and GetById). One way to accomplish this is to filter the aspect by name, as in Figure 14.

Figure 14 Filtering Methods for the Aspect

  1. public override IMessage Invoke(IMessage msg)
  2.   var methodCall = msg as IMethodCallMessage;
  3.   var methodInfo = methodCall.MethodBase as MethodInfo;
  4.   if (!methodInfo.Name.StartsWith(“Get”))
  5.     Log(“In Dynamic Proxy – Before executing ‘{0}'”,
  6.       methodCall.MethodName);
  7.     var result = methodInfo.Invoke(_decorated, methodCall.InArgs);
  8.     if (!methodInfo.Name.StartsWith(“Get”))
  9.       Log(“In Dynamic Proxy – After executing ‘{0}’ “,
  10.         methodCall.MethodName);
  11.       return new ReturnMessage(result, null, 0,
  12.        methodCall.LogicalCallContext, methodCall);
  13.   catch (Exception e)
  14.     if (!methodInfo.Name.StartsWith(“Get”))
  15.       Log(string.Format(
  16.         “In Dynamic Proxy- Exception {0} executing ‘{1}'”, e),
  17.         methodCall.MethodName);
  18.       return new ReturnMessage(e, methodCall);

The program checks if the method starts with “Get.” If it does, the program doesn’t apply the aspect. This works, but the filtering code is repeated three times. Besides that, the filter is inside the proxy, which will make you change the class every time you want to change the proxy. You can improve this by creating an IsValidMethod predicate:

  1. private static bool IsValidMethod(MethodInfo methodInfo)
  2.   return !methodInfo.Name.StartsWith(“Get”);

Now you need to make the change in only one place, but you still need to change the class every time you want to change the filter. One solution to this would be to expose the filter as a class property, so you can assign the responsibility of creating a filter to the caller. You can create a Filter property of type Predicate<MethodInfo> and use it to filter the data, as shown in Figure 15.

Figure 15 A Filtering Proxy

  1. class DynamicProxy : RealProxy
  2.   private readonly T _decorated;
  3.   private Predicate<MethodInfo> _filter;
  4.   public DynamicProxy(T decorated)
  5.     : base(typeof(T))
  6.     _decorated = decorated;
  7.     _filter = m => true;
  8.   public Predicate<MethodInfo> Filter
  9.     get { return _filter; }
  10.       if (value == null)
  11.         _filter = m => true;
  12.         _filter = value;
  13.   private void Log(string msg, object arg = null)
  14.     Console.ForegroundColor = ConsoleColor.Red;
  15.     Console.WriteLine(msg, arg);
  16.     Console.ResetColor();
  17.   public override IMessage Invoke(IMessage msg)
  18.     var methodCall = msg as IMethodCallMessage;
  19.     var methodInfo = methodCall.MethodBase as MethodInfo;
  20.     if (_filter(methodInfo))
  21.       Log(“In Dynamic Proxy – Before executing ‘{0}'”,
  22.         methodCall.MethodName);
  23.       var result = methodInfo.Invoke(_decorated, methodCall.InArgs);
  24.       if (_filter(methodInfo))
  25.         Log(“In Dynamic Proxy – After executing ‘{0}’ “,
  26.           methodCall.MethodName);
  27.         return new ReturnMessage(result, null, 0,
  28.           methodCall.LogicalCallContext, methodCall);
  29.     catch (Exception e)
  30.       if (_filter(methodInfo))
  31.         Log(string.Format(
  32.           “In Dynamic Proxy- Exception {0} executing ‘{1}'”, e),
  33.           methodCall.MethodName);
  34.       return new ReturnMessage(e, methodCall);

The Filter property is initialized with Filter = m => true. That means there’s no filter active. When assigning the Filter property, the program verifies if the value is null and, if so, it resets the filter. In the Invoke method execution, the program checks the filter result and, if true, it applies the aspect. Now the proxy creation in the factory class looks like this:

  1. public class RepositoryFactory
  2.   public static IRepository<T> Create<T>()
  3.     var repository = new Repository<T>();
  4.     var dynamicProxy = new DynamicProxy<irepository>(repository)
  5.       Filter = m => !m.Name.StartsWith(“Get”)
  6.       return dynamicProxy.GetTransparentProxy() as IRepository<T>;

The responsibility of creating the filter has been transferred to the factory.When you run the program, you should get something like Figure 16.

Output with a Filtered Proxy

Figure 16 Output with a Filtered Proxy

Notice in Figure 16 that the last two methods, GetAll and GetById (represented by “Getting entities” and “Getting entity 1”) don’t have logging around them.You can enhance the class even further by exposing the aspects as events. That way, you don’t have to change the class every time you want to change the aspect. This is shown in Figure 17.

Figure 17 A Flexible Proxy

  1. class DynamicProxy : RealProxy
  2.   private readonly T _decorated;
  3.   private Predicate<MethodInfo> _filter;
  4.   public event EventHandler<IMethodCallMessage> BeforeExecute;
  5.   public event EventHandler<IMethodCallMessage> AfterExecute;
  6.   public event EventHandler<IMethodCallMessage> ErrorExecuting;
  7.   public DynamicProxy(T decorated)
  8.     : base(typeof(T))
  9.     _decorated = decorated;
  10.     Filter = m => true;
  11.   public Predicate<MethodInfo> Filter
  12.     get { return _filter; }
  13.       if (value == null)
  14.         _filter = m => true;
  15.         _filter = value;
  16.   private void OnBeforeExecute(IMethodCallMessage methodCall)
  17.     if (BeforeExecute != null)
  18.       var methodInfo = methodCall.MethodBase as MethodInfo;
  19.       if (_filter(methodInfo))
  20.         BeforeExecute(this, methodCall);
  21.   private void OnAfterExecute(IMethodCallMessage methodCall)
  22.     if (AfterExecute != null)
  23.       var methodInfo = methodCall.MethodBase as MethodInfo;
  24.       if (_filter(methodInfo))
  25.         AfterExecute(this, methodCall);
  26.   private void OnErrorExecuting(IMethodCallMessage methodCall)
  27.     if (ErrorExecuting != null)
  28.       var methodInfo = methodCall.MethodBase as MethodInfo;
  29.       if (_filter(methodInfo))
  30.         ErrorExecuting(this, methodCall);
  31.   public override IMessage Invoke(IMessage msg)
  32.     var methodCall = msg as IMethodCallMessage;
  33.     var methodInfo = methodCall.MethodBase as MethodInfo;
  34.     OnBeforeExecute(methodCall);
  35.       var result = methodInfo.Invoke(_decorated, methodCall.InArgs);
  36.       OnAfterExecute(methodCall);
  37.       return new ReturnMessage(
  38.         result, null, 0, methodCall.LogicalCallContext, methodCall);
  39.     catch (Exception e)
  40.       OnErrorExecuting(methodCall);
  41.       return new ReturnMessage(e, methodCall);

In Figure 17, three events, BeforeExecute, AfterExecute and ErrorExecuting, are called by the methods OnBeforeExecute, OnAfterExecute and OnErrorExecuting.These methods verify whether the event handler is defined and, if it is, they check if the called method passes the filter. If so, they call the event handler that applies the aspect. The factory class now becomes something like Figure 18.

Figure 18 A Repository Factory that Sets the Aspect Events and Filter

  1. public class RepositoryFactory
  2.   private static void Log(string msg, object arg = null)
  3.     Console.ForegroundColor = ConsoleColor.Red;
  4.     Console.WriteLine(msg, arg);
  5.     Console.ResetColor();
  6.   public static IRepository<T> Create<T>()
  7.     var repository = new Repository<T>();
  8.     var dynamicProxy = new DynamicProxy<irepository>(repository);
  9.     dynamicProxy.BeforeExecute += (s, e) => Log(
  10.       “Before executing ‘{0}'”, e.MethodName);
  11.     dynamicProxy.AfterExecute += (s, e) => Log(
  12.       “After executing ‘{0}'”, e.MethodName);
  13.     dynamicProxy.ErrorExecuting += (s, e) => Log(
  14.       “Error executing ‘{0}'”, e.MethodName);
  15.     dynamicProxy.Filter = m => !m.Name.StartsWith(“Get”);
  16.     return dynamicProxy.GetTransparentProxy() as IRepository<T>;

Now you have a flexible proxy class, and you can choose the aspects to apply before executing, after executing or when there’s an error, and only for selected methods. With that, you can apply many aspects in your code with no repetition, in a simple way.

Not a Replacement 

With AOP you can add code to all layers of your application in a centralized way, with no need to repeat code. I showed how to create a generic dynamic proxy based on the Decorator design pattern that applies aspects to your classes using events and a predicate to filter the functions you want.

As you can see, the RealProxy class is a flexible class and gives you full control of the code, with no external dependencies. However, note that RealProxy isn’t a replacement for other AOP tools, such as PostSharp. PostSharp uses a completely different method. It will add intermediate language (IL) code in a post-compilation step and won’t use reflection, so it should have better performance than RealProxy. You’ll also have to do more work to implement an aspect with RealProxy than with PostSharp. With PostSharp, you need only create the aspect class and add an attribute to the class (or the method) where you want the aspect added, and that’s all.

On the other hand, with RealProxy, you’ll have full control of your source code, with no external dependencies, and you can extend and customize it as much as you want. For example, if you want to apply an aspect only on methods that have the Log attribute, you could do something like this:

  1. public override IMessage Invoke(IMessage msg)
  2.   var methodCall = msg as IMethodCallMessage;
  3.   var methodInfo = methodCall.MethodBase as MethodInfo;
  4.   if (!methodInfo.CustomAttributes
  5.     .Any(a => a.AttributeType == typeof (LogAttribute)))
  6.     var result = methodInfo.Invoke(_decorated, methodCall.InArgs);
  7.     return new ReturnMessage(result, null, 0,
  8.       methodCall.LogicalCallContext, methodCall);

Besides that, the technique used by RealProxy (intercept code and allow the program to replace it) is powerful. For example, if you want to create a mocking framework, for creating generic mocks and stubs for testing, you can use the RealProxy class to intercept all calls and replace them with your own behavior, but that’s a subject for another article!


Bruno Sonnino is a Microsoft Most Valuable Professional (MVP) located in Brazil.He’s a developer, consultant, and author, having written five Delphi books, published in Portuguese by Pearson Education Brazil, and many articles for Brazilian and U.S. magazines and Web sites.

Thanks to the following Microsoft Research technical experts for reviewing this article: James McCaffrey, Carlos Suarez and Johan Verwey James McCaffrey works for Microsoft Research in Redmond, Wash. He has worked on several Microsoft products including Internet Explorer and Bing. He can be reached at jammc@microsoft.com .

Carlos Garcia Jurado Suarez is a research software engineer in Microsoft Research, where he’s worked in the Advanced Development Team and more recently the Machine Learning Group. Earlier, he was a developer in Visual Studio working on modeling tools such as the Class Designer.