Implementing Dependency Injection using AOP

by John 5/21/2009 1:00:00 PM

Lately I've been making use of dependency injection. I've been using it in the development of applications to switch between test and production services without impacting the calling code. I have been doing this so that I might test specific parts of the code through unit testing without having to worry about setting up a database.

I'm using StructureMap in my example, which is intended to illustrate how one might go about performing dependency injection.  In the example below I've create an Invoice object. IRepository is an interface and TestRepository is a data access object which returns Invoices. Service is a class which makes uses Invoice Repositories. By using interfaces, I can at a later date with minimal change replace TestRepository with another class that performs data access against a database.

 

  Invoice=public class

  end;

  IRepository=public interface

    method FindAll:List<Invoice>;

  end;

  TestRepository=public class(IRepository)

  public

    method FindAll:List<Invoice>;

  end;

  Service=public class

  public

    constructor (repository:IRepository);

    method FindAllInvoices:List<Invoice>;

  end;

implementation

 

class method ConsoleApp.Main;

begin

  StructureMapConfiguration.BuildInstancesOf<IRepository>().TheDefaultIsConcreteType<TestRepository>();

  var service := ObjectFactory.GetInstance<Service>();

  var invoices:=service.FindAllInvoices;

end;

constructor Service(repository:IRepository);

begin

  self.repository:=repository;

end;

method Service.FindAllInvoices:List<Invoice>;

begin

result:=self.Repository.FindAll;

end; 

method Repository.FindAll:List<Invoice>;

begin

  var invoices:=new List<Invoice>;

  invoices.Add(new Invoice);

  invoices.Add(new Invoice);

  invoices.Add(new Invoice);

  result:=invoices;

end;

 

In the main method of ConsoleApp I'm doing a number of things.

1) Registering TestRepository as the type to return when an instance of IRepository is requested.

2) Requesting an instance of Service with dependencies injected.

3) Calling the FindAllInvoices on the service 

 

Its important to note that I could of done step (1) using a configuration file, which would better illustrate the power of dependency injection. I could switch between

a test and production version of the Repository with no changes to the code.

The downside I see of dependency injection is that your tied to creating instances of objects using factory method. Your also to a certain extent have a dependency on the  library your using, in this case StructureMap.

This being a continuation of my previous post, I'm going to demonstrate I think I quite an elegant solution to these two problems using AOP.

As in the previous post you can find the Aspect and an example at the Delphi Prism Aspects library.

If you open the solution, there are two projects to take a look at. Prism.StandardAspects.DependencyInjection which contains the PropertyDependencyInjector aspect and an example project showing how two use it which is called PropertyInjectorConsoleApplication.

Shown below is a sample of the code and its usage. In program.pas from the console application you can find the declaration of the InvoiceService. This time the aspect is intended for properties and I have highlighted the declaration below.

 

 InvoiceService=public class

  public

    [aspect:PropertyDependencyInjector]

    property ItemRepository:LineItemRepository;

    [aspect:PropertyDependencyInjector]

    property InvoiceRepository:InvoiceRepository;

    method GetAllInvoices:List<Invoice>;

  end;

 

Shown below is a code sample using the Service

 

    StructureMapConfiguration.BuildInstancesOf<IRepository<Invoice>>().TheDefaultIsConcreteType<InvoiceRepository>();

    StructureMapConfiguration.BuildInstancesOf<IRepository<LineItem>>().TheDefaultIsConcreteType<LineItemRepository>();

 

    var service:=new InvoiceService;

 

    if(assigned(service.InvoiceRepository))then

    begin

      var allInvoices:=service.InvoiceRepository.FindAll;

 

      if(allInvoices.Count=1)then

      begin

        Console.WriteLine(String.Format('Invoice Id{0}', allInvoices[0].Id));

      end

      else

      begin

        Console.WriteLine('No invoices ?');

      end;

    end

    else

    begin

      Console.WriteLine('No invoice repository');

    end;

In the above code example, the only way you would know the dependency injection is taking place are the two lines calling BuildInstancesOf

Otherwise your creating InvoiceService objects in the normal manner and calling the properties without even knowing anything is going on in the background.

 

Behind the scenes the aspect is modifying the getters and setters to call StructureMap. If you use Reflector to look at the final code  it should look like this

 

method InvoiceService.get_InvoiceRepository: InvoiceRepository;

begin

    if not self.@p_InvoiceRepository_injected then begin

        self.@p_InvoiceRepository_real := ObjectFactory.GetInstance<InvoiceRepository>;

        self.@p_InvoiceRepository_injected := true

    end;

    begin

        result := self.@p_InvoiceRepository_real;

        exit

    end

end;

Notice how the actual creation of property is delegated to StructureMap.

 

In conclusion, I think this is pretty cool. 

 

 

 

 

Currently rated 5.0 by 1 people

  • Currently 5/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags:

AOP | IOC | Cirrus | Delphi Prism

Data binding in a WPF Application by implementing INotifyPropertyChanged using AOP

by John 5/20/2009 8:00:00 AM

One of the big features of the May 2009 release of Delphi Prism is the introduction of support for Aspect Orientated Programming (AOP). You can read more about AOP here and Cirrus which is the AOP support in Delphi Prism.

In this blog post I'm going to implement data binding in a simple WPF application using AOP. INotifyPropertyChanged is an interface that is used to support one or two way databinding of domain objects to user interface elements. For example in a windows presentation foundation application I could bind properties of an employee object to text controls in the UI. I could then have code that updates the bound object's properties and have the UI to update as the properties are changed.

WPF supports this via the INotifyPropertyChanged interface. So taking an employee object

Employee=public class

public

property Id:Integer;

property Firstname:String;

property Lastname:String;

property Age:Integer;

end; 

 

To implement this interface I have to declare an event called PropertyChanged and fire this each time the setter of each property is called

 

Showing just the Firstname property for clarity, it might look like

Employee = public class(INotifyPropertyChanged)

private

_firstname:String;

method Employee.FirePropertyChangedEvent(value:Object; fieldName:String); 

public

property Firstname: read get_Firstname write set_Firstname;

event PropertyChanged: System.ComponentModel.PropertyChangedEventHandler; 

end; 

method Employee.get_Firstname: String;

begin

  result:=self._firstname;

end;

method Employee.set_Firstname(Value:String);

begin

  self._firstname:=value;

  FirePropertyChangedEvent(Value, 'Firstname');

end;

method Employee.FirePropertyChangedEvent(value:Object; fieldName:String);

begin 

  if((assigned(value))and(assigned(self.PropertyChanged)))then

  begin

    self.PropertyChanged(self, new PropertyChangedEventArgs(fieldName));

  end;

end;

end.

If you have domain objects with alot of properties then the lines of code can increase by quite a bit and as a result it doesn't really do much for readability. 

So lets use AOP to implement the interface.

The aspect is used to decorate a class and the completed class shown below, the only difference between the first declaration and this one is a single line at the top

  [aspect:NotifyPropertyChanged]

  Employee = public class 

  public

    property Id:Integer;

    property Firstname:String;

    property Lastname:String;

    property Age:Integer;

  end;

 The actual magic happens at compile time and you can use reflector on the assembly to see that indeed everything is there. 

 

The source code for this and other aspects can be found in the Delphi Prism Aspects project at the RemObjects code repository here 

 

The implementation for the aspect can be found in the class NotifyPropertyChangedAttribute  in the source file NotifyPropertyChangedAttribute.pas

The class implements the interface ITypeInterfaceDecorator.

Using my example, the method HandleInterface is called once during the construction of the Employee class.

The first part of the code seen below, adds an event, a private field to store the event and declares that the class implements INotifyPropertyChanged

 

  var eventDefinition:=aType.AddEvent('PropertyChanged',Services.GetType('System.ComponentModel.PropertyChangedEventHandler'),false);

  eventDefinition.Visibility:=Visibility.Public;

  var fieldDefinition:=aType.AddField('@e_PropertyChanged',Services.GetType('System.ComponentModel.PropertyChangedEventHandler'),false);

  fieldDefinition.Visibility:=Visibility.Private;

  eventDefinition.SetMember(fieldDefinition,true);

  aType.AddInterface(Services.GetType('System.ComponentModel.INotifyPropertyChanged'));

 

Its worth noting that the second parameter set to true

eventDefinition.SetMember(fieldDefinition,true); 

 

is used to indicate that a method is introduced to raise the event is generated. This is used later on in the aspect. 

 

The for loop in the next part of the method goes through each property and injects the raise method at the end of each setter after the original implementation. As a result when the setter is called the event is fired.

 

This piece of code is declaring the method call is

 

    var fireMethod:=(eventDefinition as IEvent).RaiseMethod;

    var newArg:=new NewValue(Services.GetType('System.ComponentModel.PropertyChangedEventArgs'),

      [new DataValue(PropertyDefinition.Name)]);

    var fireCall:=new ProcValue(new SelfValue(),fireMethod,

      [new SelfValue(),newArg]); 

 

and the code below is the new setter implementation, which is the original code plus the raise event code.

 

      var setValue:=new ParamValue(0);

      propertyDefinition.WriteMethod.SetBody(services,method

        begin

          Aspects.OriginalBody;

          if(assigned(unquote<Object>(setValue)))then

          begin

            unquote(fireCall);

          end;

        end);

 

The screen shot below is from the example NotifyPropertyChanged found with with the Delphi Prism aspects project linked to above. An employee instance is bound to the UI. When the user enters a new age into the textbox in the top left hand corner and hits the change age button, the age textcontrol below is updated.

 

I found implementing the aspect with Cirrus certainly takes some getting used to. It's almost as if you have to channel your inner compiler and pretend your building code. 

Cirrus is a very exciting addition to Delphi Prism and raises the bar against which other .Net languages have to compete. I hope to explore other uses for AOP in future blog posts. 

 
As a reminder the source for this and other Delphi Prism Aspects and the example can be found here
 

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags:

Cirrus | Delphi Prism | WPF | AOP

Powered by BlogEngine.NET 1.3.0.0
Theme by Mads Kristensen

About the author

Name of author John Moshakis
I'm a software developer living in Toronto..

E-mail me Send mail

Calendar

<<  September 2017  >>
MoTuWeThFrSaSu
28293031123
45678910
11121314151617
18192021222324
2526272829301
2345678

View posts in large calendar

Pages

    Recent posts

    Recent comments

    Authors

    Tags

    Don't show

      Disclaimer

      The opinions expressed herein are my own personal opinions and do not represent my employer's view in anyway.

      © Copyright 2017

      Sign in