Aspect-Oriented Programming (AOP) in .NET
-
Upload
yuriy-guts -
Category
Software
-
view
1.602 -
download
3
Transcript of Aspect-Oriented Programming (AOP) in .NET
![Page 1: Aspect-Oriented Programming (AOP) in .NET](https://reader034.fdocuments.us/reader034/viewer/2022042701/55a653211a28ab9c568b4847/html5/thumbnails/1.jpg)
Yuriy GutsSoftware Architect @ ELEKS
![Page 2: Aspect-Oriented Programming (AOP) in .NET](https://reader034.fdocuments.us/reader034/viewer/2022042701/55a653211a28ab9c568b4847/html5/thumbnails/2.jpg)
Clients
Application Services
Infrastructure Services
Desktop Browser
Desktop Application
Native Mobile App. . .
API Business Components Reporting. . .ORM
RDBMS Cache SearchIndex. . .Filesystem
![Page 3: Aspect-Oriented Programming (AOP) in .NET](https://reader034.fdocuments.us/reader034/viewer/2022042701/55a653211a28ab9c568b4847/html5/thumbnails/3.jpg)
Clients
Application Services
Infrastructure Services
Desktop Browser
Desktop Application
Native Mobile App. . .
API Business Components Search. . .ORM
RDBMS Cache SearchIndex. . .Filesystem
Cross-Cutting Concerns
Identity & Access Mgmt.
Audit
Logging
. . .
Import & Export
![Page 4: Aspect-Oriented Programming (AOP) in .NET](https://reader034.fdocuments.us/reader034/viewer/2022042701/55a653211a28ab9c568b4847/html5/thumbnails/4.jpg)
public class ReputationService : IReputationService...private readonly IUserDataService _userDataService;
public ReputationService(IUserDataService userDataService){
_userDataService = userDataService;}
public int AddReputationForQuestion(Question question){
int pointsToAdd = question.UpVotes * 5 - question.DownVotes * 2;int newReputation = _userDataService.AddReputationForUser(question.Author, pointsToAdd);return newReputation;
}
public int AddReputationForAnswer(Answer answer){
int pointsToAdd = answer.UpVotes * 10 - answer.DownVotes * 3;int newReputation = _userDataService.AddReputationForUser(answer.Author, pointsToAdd);return newReputation;
}...
![Page 5: Aspect-Oriented Programming (AOP) in .NET](https://reader034.fdocuments.us/reader034/viewer/2022042701/55a653211a28ab9c568b4847/html5/thumbnails/5.jpg)
public int AddReputationForQuestion(Question question){
int pointsToAdd = question.UpVotes * 5 - question.DownVotes * 2;int newReputation = _userDataService.AddReputationForUser(question.Author, pointsToAdd);return newReputation;
}
![Page 6: Aspect-Oriented Programming (AOP) in .NET](https://reader034.fdocuments.us/reader034/viewer/2022042701/55a653211a28ab9c568b4847/html5/thumbnails/6.jpg)
public int AddReputationForQuestion(Question question){
Console.WriteLine("{0:HH:mm:ss.fff}: AddReputationForQuestion started.", DateTime.Now);
int pointsToAdd = question.UpVotes * 5 - question.DownVotes * 2;int newReputation = _userDataService.AddReputationForUser(question.Author, pointsToAdd);
Console.WriteLine("{0:HH:mm:ss.fff}: AddReputationForQuestion completed.", DateTime.Now);return newReputation;
}
![Page 7: Aspect-Oriented Programming (AOP) in .NET](https://reader034.fdocuments.us/reader034/viewer/2022042701/55a653211a28ab9c568b4847/html5/thumbnails/7.jpg)
public int AddReputationForQuestion(Question question){
Console.WriteLine("{0:HH:mm:ss.fff}: AddReputationForQuestion started.", DateTime.Now);
if (question == null){
throw new ArgumentNullException("question");}if (question.Author == null){
throw new ArgumentNullException("question", "Author cannot be null.");}if (question.UpVotes < 0 || question.DownVotes < 0){
throw new ArgumentException("A question cannot have a negative number of votes");}
int pointsToAdd = question.UpVotes * 5 - question.DownVotes * 2;int newReputation = _userDataService.AddReputationForUser(question.Author, pointsToAdd);
Console.WriteLine("{0:HH:mm:ss.fff}: AddReputationForQuestion completed.", DateTime.Now);return newReputation;
}
![Page 8: Aspect-Oriented Programming (AOP) in .NET](https://reader034.fdocuments.us/reader034/viewer/2022042701/55a653211a28ab9c568b4847/html5/thumbnails/8.jpg)
public int AddReputationForQuestion(Question question){
Console.WriteLine("{0:HH:mm:ss.fff}: AddReputationForQuestion started.", DateTime.Now);
if (question == null) throw new ArgumentNullException("question");if (question.Author == null) throw new ArgumentNullException("question", "Author cannot be null.");if (question.UpVotes < 0 || question.DownVotes < 0) throw new ArgumentException("A question cannot have a negative number of votes");
var attemptsLeft = 3;try{
while (attemptsLeft > 0){
try{
int pointsToAdd = question.UpVotes * 5 - question.DownVotes * 2;int newReputation = _userDataService.AddReputationForUser(question.Author, pointsToAdd);
Console.WriteLine("{0:HH:mm:ss.fff}: AddReputationForQuestion completed.", DateTime.Now);return newReputation;
}catch{
attemptsLeft--;if (attemptsLeft == 0){
throw;}
}}
}catch (Exception ex){
Console.WriteLine("{0:HH:mm:ss.fff}: AddReputationForQuestion failed with exception: {1}.", DateTime.Now, ex);}throw new Exception();
}
![Page 9: Aspect-Oriented Programming (AOP) in .NET](https://reader034.fdocuments.us/reader034/viewer/2022042701/55a653211a28ab9c568b4847/html5/thumbnails/9.jpg)
public int AddReputationForQuestion(Question question){
QuestionValidator.ValidateQuestion(question);return BoundaryLogging<int>.Run("AddReputationForQuestion", () =>{
return MultipleAttemptExecutor<int>.Run(3, () =>{
int pointsToAdd = question.UpVotes * 5 - question.DownVotes * 2;int newReputation = _userDataService.AddReputationForUser(question.Author, pointsToAdd);return newReputation;
});});
}
![Page 10: Aspect-Oriented Programming (AOP) in .NET](https://reader034.fdocuments.us/reader034/viewer/2022042701/55a653211a28ab9c568b4847/html5/thumbnails/10.jpg)
[DomainValidation][BoundaryLogging][MultipleAttemptExecution(3)]public int AddReputationForQuestion(Question question){
int pointsToAdd = question.UpVotes * 5 - question.DownVotes * 2;int newReputation = _userDataService.AddReputationForUser(question.Author, pointsToAdd);return newReputation;
}
![Page 11: Aspect-Oriented Programming (AOP) in .NET](https://reader034.fdocuments.us/reader034/viewer/2022042701/55a653211a28ab9c568b4847/html5/thumbnails/11.jpg)
![Page 12: Aspect-Oriented Programming (AOP) in .NET](https://reader034.fdocuments.us/reader034/viewer/2022042701/55a653211a28ab9c568b4847/html5/thumbnails/12.jpg)
Language Compiler
AOP Post-Compiler
Source Code
IL Code
IL Code withgenerated aspects
![Page 13: Aspect-Oriented Programming (AOP) in .NET](https://reader034.fdocuments.us/reader034/viewer/2022042701/55a653211a28ab9c568b4847/html5/thumbnails/13.jpg)
IoC ContainerCalling Code
Dynamic Proxy
Original class
1
2
34
5
![Page 14: Aspect-Oriented Programming (AOP) in .NET](https://reader034.fdocuments.us/reader034/viewer/2022042701/55a653211a28ab9c568b4847/html5/thumbnails/14.jpg)
return this;
return F(this);
![Page 15: Aspect-Oriented Programming (AOP) in .NET](https://reader034.fdocuments.us/reader034/viewer/2022042701/55a653211a28ab9c568b4847/html5/thumbnails/15.jpg)
• PostSharp (IL weaving)
• Castle.DynamicProxy (call interception)
(just to name a few)
![Page 16: Aspect-Oriented Programming (AOP) in .NET](https://reader034.fdocuments.us/reader034/viewer/2022042701/55a653211a28ab9c568b4847/html5/thumbnails/16.jpg)
[Serializable]public class BoundaryLogging : OnMethodBoundaryAspect{
public override void OnEntry(MethodExecutionArgs args){
Console.WriteLine("{0:HH:mm:ss.fff}: {1} started.", DateTime.Now, args.Method.Name);}
public override void OnExit(MethodExecutionArgs args){
Console.WriteLine("{0:HH:mm:ss.fff}: {1} completed.", DateTime.Now, args.Method.Name);}
public override void OnException(MethodExecutionArgs args){
Console.WriteLine("{0:HH:mm:ss.fff}: {1} failed with exception: {2}.",DateTime.Now, args.Method.Name, args.Exception);
}}
![Page 17: Aspect-Oriented Programming (AOP) in .NET](https://reader034.fdocuments.us/reader034/viewer/2022042701/55a653211a28ab9c568b4847/html5/thumbnails/17.jpg)
[Serializable]public class MultipleAttemptExecution : MethodInterceptionAspect{
private readonly int _maxAttempts;public MultipleAttemptExecution(int maxAttempts){
_maxAttempts = maxAttempts;}
public override void OnInvoke(MethodInterceptionArgs args){
var attemptsLeft = _maxAttempts;while (attemptsLeft > 0){
try{
args.Proceed();return;
}catch{
attemptsLeft--;if (attemptsLeft == 0) throw;
}}throw new Exception("Maximum attempts reached.");
}}
![Page 18: Aspect-Oriented Programming (AOP) in .NET](https://reader034.fdocuments.us/reader034/viewer/2022042701/55a653211a28ab9c568b4847/html5/thumbnails/18.jpg)
[DomainValidation][BoundaryLogging][MultipleAttemptExecution(3)]public int AddReputationForQuestion(Question question){
int pointsToAdd = question.UpVotes * 5 - question.DownVotes * 2;int newReputation = _userDataService.AddReputationForUser(question.Author, pointsToAdd);return newReputation;
}
![Page 19: Aspect-Oriented Programming (AOP) in .NET](https://reader034.fdocuments.us/reader034/viewer/2022042701/55a653211a28ab9c568b4847/html5/thumbnails/19.jpg)
![Page 20: Aspect-Oriented Programming (AOP) in .NET](https://reader034.fdocuments.us/reader034/viewer/2022042701/55a653211a28ab9c568b4847/html5/thumbnails/20.jpg)
• [Authorize] attribute in ASP.NET MVC
• HttpModules in ASP.NET lifecycle
• Anything else?
![Page 21: Aspect-Oriented Programming (AOP) in .NET](https://reader034.fdocuments.us/reader034/viewer/2022042701/55a653211a28ab9c568b4847/html5/thumbnails/21.jpg)
• Logging & Audit
• Transactions
• Security
• Caching
• Exception Management
• Generating and validating code
![Page 22: Aspect-Oriented Programming (AOP) in .NET](https://reader034.fdocuments.us/reader034/viewer/2022042701/55a653211a28ab9c568b4847/html5/thumbnails/22.jpg)
1. Introduces “magic”, can reduce understanding of the big picture (*).
2. Requires special tools or code decorations.
3. Even mature frameworks have bugs.
(*) Greg Young:www.infoq.com/presentations/8-lines-code-refactoring
![Page 23: Aspect-Oriented Programming (AOP) in .NET](https://reader034.fdocuments.us/reader034/viewer/2022042701/55a653211a28ab9c568b4847/html5/thumbnails/23.jpg)
yuriy.guts @ eleks.com
https://github.com/YuriyGuts/refactoring-with-aop