2012-04-12 - AOP .NET UserGroup Niederrhein

3,270 views
3,418 views

Published on

Published in: Technology, Business
0 Comments
2 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
3,270
On SlideShare
0
From Embeds
0
Number of Embeds
1,818
Actions
Shares
0
Downloads
15
Comments
0
Likes
2
Embeds 0
No embeds

No notes for slide

2012-04-12 - AOP .NET UserGroup Niederrhein

  1. 1. AOP mit .NET12.04.2012Dipl.-Inf. (FH) Johannes Hoppe
  2. 2. Johannes HoppeASP.NET MVC Webentwickler www.johanneshoppe.de
  3. 3. 01Architektur und Patterns
  4. 4. Patternssoftware craftsmanship
  5. 5. Business Codepublic class CustomerProcesses{ public void RentBook( int bookId, int customerId ) { Book book = Book.GetById( bookId ); Customer customer = Customer.GetById( customerId ); book.RentedTo = customer; customer.AccountLines.Add( string.Format( "Rental of book {0}.", book ), book.RentalPrice); customer.Balance -= book.RentalPrice; }}
  6. 6. Business Code
  7. 7. Business Codepublic class CustomerProcesses{ public void RentBook( int bookId, int customerId ) { Book book = Book.GetById( bookId ); Customer customer = Customer.GetById( customerId ); book.RentedTo = customer; customer.AccountLines.Add( string.Format( "Rental of book {0}.", book ), book.RentalPrice); customer.Balance -= book.RentalPrice; }}
  8. 8. Business Code+ Logging internal class CustomerProcesses { private static readonly TraceSource trace = new TraceSource( typeof (CustomerProcesses).FullName ); public void RentBook( int bookId, int customerId ) { trace.TraceInformation( "Entering CustomerProcesses.CreateCustomer( bookId = {0}, customerId = {1} )", bookId, customerId ); try { Book book = Book.GetById( bookId ); Customer customer = Customer.GetById( customerId ); book.RentedTo = customer; customer.AccountLines.Add( string.Format( "Rental of book {0}.", book ), book.RentalPrice ); customer.Balance -= book.RentalPrice; trace.TraceInformation( "Leaving CustomerProcesses.CreateCustomer( bookId = {0}, customerId = {1} )", bookId, customerId ); } catch ( Exception e ) { trace.TraceEvent( TraceEventType.Error, 0, "Exception: CustomerProcesses.CreateCustomer( bookId = {0}, customerId = {1} ) failed : {2}", bookId, customerId, e.Message ); throw; } } }
  9. 9. Business Code+ Logging internal class CustomerProcesses+ Vorbedingungen { private static readonly TraceSource trace = new TraceSource(typeof(CustomerProcesses).FullName); public void RentBook(int bookId, int customerId) { if (bookId <= 0) throw new ArgumentOutOfRangeException("bookId"); if (customerId <= 0) throw new ArgumentOutOfRangeException("customerId"); trace.TraceInformation( "Entering CustomerProcesses.CreateCustomer( bookId = {0}, customerId = {1} )", bookId, customerId); try { Book book = Book.GetById(bookId); Customer customer = Customer.GetById(customerId); book.RentedTo = customer; customer.AccountLines.Add(string.Format("Rental of book {0}.", book), book.RentalPrice); customer.Balance -= book.RentalPrice; trace.TraceInformation( "Leaving CustomerProcesses.CreateCustomer( bookId = {0}, customerId = {1} )“, bookId, customerId); } catch (Exception e) { trace.TraceEvent(TraceEventType.Error, 0, "Exception: CustomerProcesses.CreateCustomer( bookId = {0}, customerId = {1} ) failed : {2}", bookId, customerId, e.Message); throw; } } }
  10. 10. Business Code + Logging + Transaktionen + Vorbedingungeninternal class CustomerProcesses ts.Complete();{ } private static readonly TraceSource trace = new TraceSource(typeof(CustomerProcesses).FullName); break; } public void RentBook(int bookId, int customerId) catch (TransactionConflictException) { { if (bookId <= 0) if (i < 3) throw new ArgumentOutOfRangeException("bookId"); continue; if (customerId <= 0) else throw new ArgumentOutOfRangeException("customerId"); throw; } trace.TraceInformation( } "Entering CustomerProcesses.CreateCustomer( bookId = {0}, customerId = {1} )“, bookId, customerId); trace.TraceInformation( "Leaving CustomerProcesses.CreateCustomer( try bookId = {0}, customerId = {1} )", { bookId, customerId); for (int i = 0; ; i++) } { catch (Exception e) try { { trace.TraceEvent(TraceEventType.Error, 0, using (var ts = new TransactionScope()) "Exception: CustomerProcesses.CreateCustomer( bookId = {0}, { customerId = {1} ) failed : {2}", Book book = Book.GetById(bookId); bookId, customerId, e.Message); Customer customer = throw; Customer.GetById(customerId); } } book.RentedTo = customer; customer.AccountLines.Add( } string.Format("Rental of book {0}.", book), book.RentalPrice); customer.Balance -= book.RentalPrice;
  11. 11. Business Code + Logging + Transaktionen + Vorbedingungen + Exception Handlinginternal class CustomerProcesses{ ts.Complete(); private static readonly TraceSource trace = } new TraceSource(typeof(CustomerProcesses).FullName); break; public void RentBook(int bookId, int customerId) } { catch ( TransactionConflictException ) if (bookId <= 0) throw new ArgumentOutOfRangeException("bookId"); { if (customerId <= 0) if ( i < 3 ) throw new ArgumentOutOfRangeException("customerId"); continue; else try throw; { } trace.TraceInformation( } "Entering CustomerProcesses.CreateCustomer( bookId = {0}, customerId = {1} )", trace.TraceInformation( bookId, customerId ); "Leaving CustomerProcesses.CreateCustomer( bookId = {0}, customerId = {1} )", try bookId, customerId ); { } for ( int i = 0;; i++ ) catch ( Exception e ) { { try trace.TraceEvent( TraceEventType.Error, 0, { "Exception: CustomerProcesses.CreateCustomer( using ( var ts = new TransactionScope() ) bookId = {0}, customerId = {1} ) failed : {2}", { bookId, customerId, e.Message ); Book book = Book.GetById( bookId ); throw; Customer customer = Customer.GetById( customerId ); } } book.RentedTo = customer; catch ( Exception e ) customer.AccountLines.Add( { string.Format( "Rental of book {0}.", book ), if (ExceptionManager.Handle(e)) throw; book.RentalPrice ); } customer.Balance -= book.RentalPrice; }
  12. 12. Business Code+ Logging + Transaktionen+ Vorbedingungen + Exception Handling+ Feature X+ Feature Y+ Feature Z+…
  13. 13. Kern- Seperationfunktionalitäten of Concerns (Core Concerns)
  14. 14. VS
  15. 15. VS Nicht- Funktionale Anforderungen (Crosscutting Concerns)
  16. 16. Cross-Cutting Concerns Security Data Binding Exception Handling Thread Sync Tracing Caching Monitoring Validation Transaction …
  17. 17. OOP OOP+ AOP
  18. 18. Spring.NETPostSharp LinFu Castle MS UnityBuild-Time Hybrid Run-Time
  19. 19. Build-Time: “Statisch” Run-Time: “Dynamisch”Erfolgt bei Kompilierung Erfolgt zur LaufzeitCode wird direkt verändert Code bleibt unverändertZur Laufzeit keine Änderungen Zur Laufzeit Änderungen möglichAuch auf Properties, Felder, Aufruf wird über ProxyEvents anwendbar umgeleitetKeine Interfaces erforderlich idR. Interfaces erforderlich (Proxy)
  20. 20. 02Live Coding
  21. 21. LoggingLogTimeAspect webnoteaop.codeplex.com
  22. 22. ExceptionsConvertExceptionAspect webnoteaop.codeplex.com
  23. 23. ValidierungValidationGuardAspect webnoteaop.codeplex.com
  24. 24. CachingSimpleCacheAspect webnoteaop.codeplex.com
  25. 25. 03AOP 1 x 1
  26. 26. AspectJ Begriffe Join Point Pointcut Advice Aspect
  27. 27. AspectJ Begriffe Join Point Pointcut Advice Aspect
  28. 28. IL Code Vorher [LogTimeAspect] public ActionResult Index() { IEnumerable<NoteWithCategories> notes = this.WebNoteService.ReadAll(); return View(notes); }
  29. 29. IL Code Nachher public ActionResult Index() { ActionResult CS$1$2__returnValue; MethodExecutionArgs CS$0$3__aspectArgs = new MethodExecutionArgs(null, null); <>z__Aspects.a68.OnEntry(CS$0$3__aspectArgs); try { IEnumerable<NoteWithCategories> notes = this.WebNoteService.ReadAll(); ActionResult CS$1$0000 = base.View(notes); CS$1$2__returnValue = CS$1$0000; } finally { <>z__Aspects.a68.OnExit(CS$0$3__aspectArgs); } return CS$1$2__returnValue; }
  30. 30. Originale Methode Aspekt Klasse OnEntry try { Method Body OnSuccess } catch (Exception e) { OnException } finally { OnExit } : OnMethodBoundaryAspect
  31. 31. 04Installation
  32. 32. www.sharpcrafters.com/postsharp/download
  33. 33. nugethttp://nuget.org/packages/PostSharp
  34. 34. Spring.NET PostSharpspringframework.net sharpcrafters.comCastle Demo Downloadcastleproject.org webnoteaop.codeplex.comUnityunity.codeplex.com
  35. 35. FRAGEN?
  36. 36. Bis bald› 10.05.2012 – .NET UG Karlsruhe: NoSQL› 14.05.2012 – .NET Developer Conference (DDC) .Nürnberg: NoSQL
  37. 37. Vielen Dank!
  38. 38. Primitive Aspekt-Typen› MethodBoundaryAspect › LocationInterceptionAspect › OnEntry › OnGetValue › OnSuccess › OnSetValue › OnException › OnExit › EventInterceptionAspect › OnAddHandler› OnExceptionAspect › OnRemoveHandler › OnException › OnInvokeHandler› MethodInterceptionAspect › MethodImplementationAspect › OnInvoke › OnInvoke › CompositionAspect › CreateImplementationObject
  39. 39. BildnachweiseAusgewählter Ordner © Spectral-Design – Fotolia.comWarnhinweis-Schild © Sascha Tiebel – Fotolia.comListe abhaken © Dirk Schumann – Fotolia.com3D rendering of an architecture model 2 © Franck Boston – Fotolia.comHealthcare © ArtmannWitte – Fotolia.comStressed businessman © Selecstock – Fotolia.comFunny cartoon boss © artenot – Fotolia.com

×