-
Notifications
You must be signed in to change notification settings - Fork 7
Property Aspects
Let's change a bit the contract that we've created in the Atom Composite
example by refactoring the Code
method to a property.
using NCop.Mixins.Framework;
using NCop.Composite.Framework;
[TransientComposite]
[Mixins(typeof(CSharpDeveloperMixin))]
public interface IDeveloper
{
string Code { get; set; }
}
public class CSharpDeveloperMixin : IDeveloper
{
public string Code { get; set; }
}
We want to apply the aspect on the Code
property therefore we need to create a new aspect that is derived from PropertyInterceptionAspect<string>
.
When you derive from a property interception aspect you'll get the option to insert pieces of code in several points in the program (a.k.a join points):
- OnGetValue - Called when the value of this property is retrieved.
- OnSetValue - Called when the value of this property is changed.
Each code piece is called advice. Let's write some code on each advice.
public class SimplePropertyInterceptionAspect : PropertyInterceptionAspect<string>
{
public override void OnGetValue(PropertyInterceptionArgs<string> args) {
Console.WriteLine("OnGetValue");
args.ProceedGetValue();
}
public override void OnSetValue(PropertyInterceptionArgs<string> args) {
Console.WriteLine("OnSetValue");
args.ProceedSetValue();
}
}
In order for NCop to apply SimplePropertyInterceptionAspect
as an aspect we need to annotate the Code
property with PropertyInterceptionAspectAttribute
attribute.
using NCop.Mixins.Framework;
using NCop.Composite.Framework;
using NCop.Aspects.Framework;
[TransientComposite]
[Mixins(typeof(CSharpDeveloperMixin))]
public interface IDeveloper
{
[PropertyInterceptionAspect(typeof(SimplePropertyInterceptionAspect))]
string Code { get; set; }
}
An aspect can be placed also on the Mixin's property.
public class CSharpDeveloperMixin : IDeveloper
{
[PropertyInterceptionAspect(typeof(SimplePropertyInterceptionAspect))]
public string Code { get; set; }
}
The last thing that we have to do is create a CompositeContainer
which will handle two things:
- Craft the real implementation in runtime.
- Act as a Dependency Injection Container that will resolve our type.
using System;
using NCop.Aspects.Framework;
using NCop.Composite.Framework;
using NCop.Mixins.Framework;
class Program
{
static void Main(string[] args) {
IDeveloper developer = null;
var container = new CompositeContainer();
container.Configure();
developer = container.Resolve<IDeveloper>();
developer.Code = "C# coding";
Console.WriteLine(developer.Code);
}
}
The expected output should be:
"OnSetValue"
"OnGetValue"
"C# coding"
Your end result of the code should be similar to this:
using System;
using NCop.Aspects.Framework;
using NCop.Composite.Framework;
using NCop.Mixins.Framework;
namespace NCop.Samples
{
[TransientComposite]
[Mixins(typeof(CSharpDeveloperMixin))]
public interface IDeveloper
{
[PropertyInterceptionAspect(typeof(SimplePropertyInterceptionAspect))]
string Code { get; set; }
}
public class SimplePropertyInterceptionAspect : PropertyInterceptionAspect<string>
{
public override void OnGetValue(PropertyInterceptionArgs<string> args) {
Console.WriteLine("OnGetValue");
args.ProceedGetValue();
}
public override void OnSetValue(PropertyInterceptionArgs<string> args) {
Console.WriteLine("OnSetValue");
args.ProceedSetValue();
}
}
public class CSharpDeveloperMixin : IDeveloper
{
public string Code { get; set; }
}
class Program
{
static void Main(string[] args) {
IDeveloper developer = null;
var container = new CompositeContainer();
container.Configure();
developer = container.Resolve<IDeveloper>();
developer.Code = "C# coding";
Console.WriteLine(developer.Code);
}
}
}