post sharp talk
DESCRIPTION
Introduction to Aspect Orientated Programming in .NET using PostSharpTRANSCRIPT
![Page 1: Post Sharp Talk](https://reader035.vdocument.in/reader035/viewer/2022062703/5553b669b4c905d4448b4d83/html5/thumbnails/1.jpg)
PostSharpAOP in .NET
Business Rules + Plumbing = Enterprise Software
David RossW: www.pebblesteps.comE: [email protected]
![Page 2: Post Sharp Talk](https://reader035.vdocument.in/reader035/viewer/2022062703/5553b669b4c905d4448b4d83/html5/thumbnails/2.jpg)
Application ConcernsCore CrosscuttingFunctional
RequirementsDomain/Object
ModelBusiness Logic
Non-functional Requirements
Model needs to provide capability for many different layers
At layer boundariesLoggingValidationSecurityData marshalling
![Page 3: Post Sharp Talk](https://reader035.vdocument.in/reader035/viewer/2022062703/5553b669b4c905d4448b4d83/html5/thumbnails/3.jpg)
Crosscutting Concerns – PlumbingLogging/Monitoring/AlertingType safety (Beyond value types int, string)
Validation/EnforcementSecurity
Authorisation/AuthenticationData Binding
INotifyPropertyChanged DependencyProperties
TransactionsConcurrency - Locking
![Page 4: Post Sharp Talk](https://reader035.vdocument.in/reader035/viewer/2022062703/5553b669b4c905d4448b4d83/html5/thumbnails/4.jpg)
Aspects - Reduce noise in sourceMove plumbing out of source, but keep behaviour
the same
AdviceThe duplicated plumbing code we are removingTypically under 30 lines of codeBehaviour that is injected at a join point
Join pointsPlaces within the code where the Aspect is insertedExamples
Entry/Exit of a method or propertyClass’s Type Definition
![Page 5: Post Sharp Talk](https://reader035.vdocument.in/reader035/viewer/2022062703/5553b669b4c905d4448b4d83/html5/thumbnails/5.jpg)
Aspects Lingo
Point cutLocates Join Points to apply adviceFilter driven – Automatic injection
Find all Methods, of type Setter, in all classes where Namespace equals “Application.Entities”
Attribute driven – Manual injection
![Page 6: Post Sharp Talk](https://reader035.vdocument.in/reader035/viewer/2022062703/5553b669b4c905d4448b4d83/html5/thumbnails/6.jpg)
Aspects LingoWeavingProcess of injecting functionality back into a
componentCan be performed by
Text post processor – Magic comments can replaced by code
Proxy container – Uses decorator pattern/hooks to allow code to be inserted
Binary manipulation - Modifying assemblies - by replacing and injecting IL code
![Page 7: Post Sharp Talk](https://reader035.vdocument.in/reader035/viewer/2022062703/5553b669b4c905d4448b4d83/html5/thumbnails/7.jpg)
Compile-time MSIL Injection process
Copyright © by Gael Fraiteur
If Postsharp modifies a type’s signature...•No Intellisense for a referenced projects that are modified•Intellisense for referenced assemblies that are modified
![Page 8: Post Sharp Talk](https://reader035.vdocument.in/reader035/viewer/2022062703/5553b669b4c905d4448b4d83/html5/thumbnails/8.jpg)
PostSharp WeavingCompile time Weaving - LGPL
Automatically if a component references PostSharp.Laos.dll – Default Install configures MSBuild
Manual application using an MSBuild task
Run time Weaving – GPL/Commercial LicenseManual via PostSharp.Core.dllStatically modify the assembly just before it is
loaded into the domain
![Page 9: Post Sharp Talk](https://reader035.vdocument.in/reader035/viewer/2022062703/5553b669b4c905d4448b4d83/html5/thumbnails/9.jpg)
Example classpublic class Demo{
public Demo(){ActivityRecorder.Record("In constructor");}public void Foo(){ActivityRecorder.Record("In Foo");}public void StaticFoo(){ActivityRecorder.Record("In StaticFoo");}
}
![Page 10: Post Sharp Talk](https://reader035.vdocument.in/reader035/viewer/2022062703/5553b669b4c905d4448b4d83/html5/thumbnails/10.jpg)
[Test] public void Verify_Aspect_Called_On_Method_Invocation() {
var d = new Demo ();d.Foo();d.StaticFoo();
ActivityRecorder.AssertActivityOccured("In constructor");
ActivityRecorder.AssertActivityOccured("Calling Void Foo()");ActivityRecorder.AssertActivityOccured("In Foo");
ActivityRecorder.AssertActivityOccured("Calling Void StaticFoo()");ActivityRecorder.AssertActivityOccured("In StaticFoo");
ActivityRecorder.AssertNoMoreActivities();}
![Page 11: Post Sharp Talk](https://reader035.vdocument.in/reader035/viewer/2022062703/5553b669b4c905d4448b4d83/html5/thumbnails/11.jpg)
Method Invocation - Aspect[Serializable]public class ExampleOnMethodInvocationAspect :
OnMethodInvocationAspect {
public override void OnInvocation(MethodInvocationEventArgs context) {
ActivityRecorder.Record(string.Format("Calling {0}", context.Delegate.Method.Replace(“~”, “”));
// Do I want to continue??
context.Proceed(); }}
![Page 12: Post Sharp Talk](https://reader035.vdocument.in/reader035/viewer/2022062703/5553b669b4c905d4448b4d83/html5/thumbnails/12.jpg)
Code after Injectionprivate void ~Foo() { ActivityRecorder.Record("In Foo");}
[DebuggerNonUserCode, CompilerGenerated]public void Foo(){
Delegate delegateInstance = new ~PostSharp~Laos~Implementation.~delegate~0(this.~Foo);
MethodInvocationEventArgs eventArgs = new MethodInvocationEventArgs(delegateInstance, null);
~PostSharp~Laos~Implementation.SkillsMatter.PostSharp.Aspects.
ExampleOnMethodInvocationAspect~1.OnInvocation(eventArgs);
}
![Page 13: Post Sharp Talk](https://reader035.vdocument.in/reader035/viewer/2022062703/5553b669b4c905d4448b4d83/html5/thumbnails/13.jpg)
Filter based Point Cut [assembly:
ExampleOnMethodInvocationAspect(AttributeTargetAssemblies =
"SkillsMatter.PostSharp", AttributeTargetTypes = "SkillsMatter.PostSharp.OnMethodInvocation.*")]
Very simple to apply changes to all business objects in the solution with a single filter...
![Page 14: Post Sharp Talk](https://reader035.vdocument.in/reader035/viewer/2022062703/5553b669b4c905d4448b4d83/html5/thumbnails/14.jpg)
On Boundary Invocation - Aspect
[Serializable]public class ExampleOnMethodBoundaryAspect : OnMethodBoundaryAspect{
public override void OnEntry(MethodExecutionEventArgs eventArgs) {ActivityRecorder.Record(string.Format("Before {0}",
eventArgs.Method));}
public override void OnExit(MethodExecutionEventArgs eventArgs) {ActivityRecorder.Record(string.Format("After {0}", eventArgs.Method));
}
public override void OnException(MethodExecutionEventArgs eventArgs) {ActivityRecorder.Record(string.Format("After {0}", eventArgs.Method));
}}
![Page 15: Post Sharp Talk](https://reader035.vdocument.in/reader035/viewer/2022062703/5553b669b4c905d4448b4d83/html5/thumbnails/15.jpg)
[Test] public void Verify_Aspect_Called_On_Method_Boundary() {var e = new Demo();
e.Foo();e.StaticFoo();
ActivityRecorder.AssertActivityOccured("Before Void .ctor()");ActivityRecorder.AssertActivityOccured("In constructor");ActivityRecorder.AssertActivityOccured("After Void .ctor()");
ActivityRecorder.AssertActivityOccured("Before Void Foo()");ActivityRecorder.AssertActivityOccured("In Foo");ActivityRecorder.AssertActivityOccured("After Void Foo()");
ActivityRecorder.AssertActivityOccured("Before Void StaticFoo()");ActivityRecorder.AssertActivityOccured("In StaticFoo");ActivityRecorder.AssertActivityOccured("After Void StaticFoo()");
ActivityRecorder.AssertNoMoreActivities();}
![Page 16: Post Sharp Talk](https://reader035.vdocument.in/reader035/viewer/2022062703/5553b669b4c905d4448b4d83/html5/thumbnails/16.jpg)
Manual Point Cutpublic class FoodQuestionaire{
[RegularExpressionValidator("^([A-PR-UWYZ0-9][A-HK-Y0-9][AEHMNPRTVXY0-9]?[ABEHMNPRVWXY0-9]? {1,2}[0-9][ABD-HJLN-UW-Z]{2}|GIR 0AA)$")]
public string Postcode { get; set; }
[RangeValidator(0, 5)]public int? LikesDiary { get; set; }[RangeValidator(0, 5)]public int? LikesBeef { get; set; }[RangeValidator(0, 5)]public int? LikesFish { get; set; }
}
![Page 17: Post Sharp Talk](https://reader035.vdocument.in/reader035/viewer/2022062703/5553b669b4c905d4448b4d83/html5/thumbnails/17.jpg)
public override void OnEntry(MethodExecutionEventArgs eventArgs) {
if (!eventArgs.Method.Name.StartsWith(“set_"))return;
int value = (int)args[0];if (value < LowerBoundary || value > UpperBoundary)
throw new ValidationException("Value must be between " + LowerBoundary + " and “ +
UpperBoundary);
base.OnEntry(eventArgs);}
![Page 18: Post Sharp Talk](https://reader035.vdocument.in/reader035/viewer/2022062703/5553b669b4c905d4448b4d83/html5/thumbnails/18.jpg)
[Test]public void RangeTest() {
FoodQuestionaire q = new FoodQuestionaire();
q.LikesBeef = 5;Assert.AreEqual(5, q.LikesBeef);Assert.Throws<ValidationException>(() => q.LikesBeef = 100);Assert.Throws<ValidationException>(() => q.LikesBeef = -3);Assert.AreEqual(5, q.LikesBeef);
q.Postcode = "E14 0AN";Assert.AreEqual("E14 0AN", q.Postcode);Assert.Throws<ValidationException>(() => q.Postcode = "Hello World");Assert.AreEqual("E14 0AN", q.Postcode);
}
![Page 19: Post Sharp Talk](https://reader035.vdocument.in/reader035/viewer/2022062703/5553b669b4c905d4448b4d83/html5/thumbnails/19.jpg)
On Method Boundary can be used for...How long did a method take to execute?Resource Management – Create resource
before a method is called and release afterwardsTransactions – Commit/Rollback as requiredConcurrency – Mutual Exclusion around code
![Page 20: Post Sharp Talk](https://reader035.vdocument.in/reader035/viewer/2022062703/5553b669b4c905d4448b4d83/html5/thumbnails/20.jpg)
Other AspectsImplement Method Aspect
Replace a method’s content with the advice in the aspect
Useful for modifying 3rd party components
Composition AspectAllows an interface/state to be injected into a
componentUsed to simulate multiple inheritanceExamples include
Adding .NET Win Form data binding to a POCO Adding Entity Framework interfaces to a POCO
![Page 21: Post Sharp Talk](https://reader035.vdocument.in/reader035/viewer/2022062703/5553b669b4c905d4448b4d83/html5/thumbnails/21.jpg)
Breaking the BuildAll NHibernate methods must be virtual – Davy Brion
public class RequireVirtualMethodsAndProperties : OnMethodBoundaryAspect {
public override bool CompileTimeValidate(MethodBase method) { if (!method.IsVirtual) { string methodName = method.DeclaringType.FullName + “.”
+ method.Name; var message = new Message(SeverityType.Fatal, “MustBeVirtual”, string.Format(“{0} must be virtual”, methodName), GetType().Name); MessageSource.MessageSink.Write(message); return false; } return true; }}
![Page 22: Post Sharp Talk](https://reader035.vdocument.in/reader035/viewer/2022062703/5553b669b4c905d4448b4d83/html5/thumbnails/22.jpg)
Learn more...Talk’s source code @ www.pebblesteps.com
http://www.postsharp.org/http://davybrion.com/blog/category/postsharp/http://www.codeplex.com/ValidationAspectshttp://www.eclipse.org/aspectj/doc/released/
progguide/
Thanks for listeningQuestions?