2011-06-27 - AOP - .NET User Group Rhein Neckar

37
Aspekt Orientierte Programmierung mit .NET Eine praktische Einführung 27.06.2011 Dipl.-Inf. (FH) Johannes Hoppe

description

 

Transcript of 2011-06-27 - AOP - .NET User Group Rhein Neckar

Page 1: 2011-06-27 - AOP - .NET User Group Rhein Neckar

AspektOrientierteProgrammierungmit .NET

Eine praktische Einführung

27.06.2011Dipl.-Inf. (FH) Johannes Hoppe

Page 2: 2011-06-27 - AOP - .NET User Group Rhein Neckar

AOP

Johannes HoppeASP.NET MVC Webentwickler

www.johanneshoppe.de

Page 3: 2011-06-27 - AOP - .NET User Group Rhein Neckar

AOP

Architektur und Patterns

01

Page 4: 2011-06-27 - AOP - .NET User Group Rhein Neckar

AOP

PatternsEntwurfsmuster

==unser täglicher Job

Page 5: 2011-06-27 - AOP - .NET User Group Rhein Neckar

AOPBeispiel

View

Controller

Model(Business Layer)

Service Layer

Repository Layer

Data Access Layer

Page 6: 2011-06-27 - AOP - .NET User Group Rhein Neckar

AOP

Aber…

Page 7: 2011-06-27 - AOP - .NET User Group Rhein Neckar

AOPBusiness Code

public 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; }}

Page 8: 2011-06-27 - AOP - .NET User Group Rhein Neckar

AOPBusiness Code

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; }   }}

+ Logging

Page 9: 2011-06-27 - AOP - .NET User Group Rhein Neckar

AOPBusiness Code

internal class CustomerProcesses{ 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; } }}

+ Logging+ Vorbedingungen

Page 10: 2011-06-27 - AOP - .NET User Group Rhein Neckar

AOPBusiness Code

+ Logging + Transaktionen + Vorbedingungen

internal class CustomerProcesses{ 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 { for (int i = 0; ; i++) { try { using (var ts = new TransactionScope()) { 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;  ts.Complete(); }

  break; } catch (TransactionConflictException) { if (i < 3) continue; else throw; } }  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; } }

}

Page 11: 2011-06-27 - AOP - .NET User Group Rhein Neckar

AOPBusiness Code

+ Logging + Transaktionen + Vorbedingungen + Exception Handling

internal class CustomerProcesses{ 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");  try { trace.TraceInformation( "Entering CustomerProcesses.CreateCustomer( bookId = {0}, customerId = {1} )", bookId, customerId );  try { for ( int i = 0;; i++ ) { try { using ( var ts = new TransactionScope() ) { 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; 

ts.Complete(); }  break; } catch ( TransactionConflictException ) { if ( i < 3 ) continue; else throw; } }  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; } } catch ( Exception e ) { if (ExceptionManager.Handle(e)) throw; } }}

Page 12: 2011-06-27 - AOP - .NET User Group Rhein Neckar

AOPBusiness Code

+ Logging + Transaktionen + Vorbedingungen + Exception Handling

+ Feature X+ Feature Y+ Feature Z+ …

Page 13: 2011-06-27 - AOP - .NET User Group Rhein Neckar

AOP

Kern-funktionalität

en(Core Concerns)

Seperationof

Concerns

Page 14: 2011-06-27 - AOP - .NET User Group Rhein Neckar

AOP

VS

Page 15: 2011-06-27 - AOP - .NET User Group Rhein Neckar

AOP

Nicht-Funktionale

Anforderungen

(Crosscutting Concerns)

VS

Page 16: 2011-06-27 - AOP - .NET User Group Rhein Neckar

AOP

SecurityException

HandlingTracingMonitoringTransaction

Data BindingThread SyncCachingValidation…

Cross-Cutting Concerns

Page 17: 2011-06-27 - AOP - .NET User Group Rhein Neckar

AOP

OOP

OOP

+ AOP

Page 18: 2011-06-27 - AOP - .NET User Group Rhein Neckar

AOP

Build-Time Run-TimeHybrid

PostSharp

Spring.NETCastleMS Unity

LinFu

Page 19: 2011-06-27 - AOP - .NET User Group Rhein Neckar

AOP

Build-Time: “Statisch” Run-Time: “Dynamisch”

Erfolgt bei Kompilierung

Code wird direkt verändert

Keine Interfaces erforderlich

Zur Laufzeit keine Änderungen

Auch auf Properties, Felder,Events anwendbar

Kann Member und Interfaces hinzufügen

Erfolgt zur Laufzeit

Code bleibt unverändert

Aufruf wird über Proxy umgeleitet

Zur Laufzeit keine Änderungen

Aufruf wird über Proxyumgeleitet

Aspekte zur Laufzeitkonfigurierbar

Page 20: 2011-06-27 - AOP - .NET User Group Rhein Neckar

AOP

Live Coding

02

Page 21: 2011-06-27 - AOP - .NET User Group Rhein Neckar

AOP

Page 22: 2011-06-27 - AOP - .NET User Group Rhein Neckar

AOP

LoggingLogTimeAspect

webnoteaop.codeplex.com

Page 23: 2011-06-27 - AOP - .NET User Group Rhein Neckar

AOP

ExceptionsConvertExceptionAspect

webnoteaop.codeplex.com

Page 24: 2011-06-27 - AOP - .NET User Group Rhein Neckar

AOP

ValidierungValidationGuardAspect

webnoteaop.codeplex.com

Page 25: 2011-06-27 - AOP - .NET User Group Rhein Neckar

AOP

CachingSimpleCacheAspect

webnoteaop.codeplex.com

Page 26: 2011-06-27 - AOP - .NET User Group Rhein Neckar

AOP

Page 27: 2011-06-27 - AOP - .NET User Group Rhein Neckar

AOP

AOP 1 x 1

03

Page 28: 2011-06-27 - AOP - .NET User Group Rhein Neckar

AOPAspectJ Begriffe

Join PointPointcutAdviceAspect

Page 29: 2011-06-27 - AOP - .NET User Group Rhein Neckar

AOPAspectJ Begriffe

Join PointPointcutAdviceAspect

Page 30: 2011-06-27 - AOP - .NET User Group Rhein Neckar

AOPIL Code Vorher

[LogTimeAspect]public ActionResult Index(){ IEnumerable<NoteWithCategories> notes = this.WebNoteService.ReadAll(); return View(notes);}

Page 31: 2011-06-27 - AOP - .NET User Group Rhein Neckar

AOPIL 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;}

Page 32: 2011-06-27 - AOP - .NET User Group Rhein Neckar

AOP

: OnMethodBoundaryAspect

try{

}catch (Exception e){ }finally{

}

OnEntry

OnSuccess

OnException

OnExit

Originale Methode Aspect Klasse

Method Body

Page 33: 2011-06-27 - AOP - .NET User Group Rhein Neckar

AOPLinks

Spring.NETspringframework.net

Castlecastleproject.org

Unityunity.codeplex.com

PostSharpsharpcrafters.com

Demo Downloadwebnoteaop.codeplex.com

Page 34: 2011-06-27 - AOP - .NET User Group Rhein Neckar

FRAGEN?

Page 35: 2011-06-27 - AOP - .NET User Group Rhein Neckar

Vielen Dank!Johannes Hoppe

Page 36: 2011-06-27 - AOP - .NET User Group Rhein Neckar

AOP

› MethodBoundaryAspect› OnEntry› OnSuccess› OnException› OnExit

› OnExceptionAspect› OnException

› MethodInterceptionAspect› OnInvoke

› LocationInterceptionAspect› OnGetValue› OnSetValue

› EventInterceptionAspect› OnAddHandler› OnRemoveHandler› OnInvokeHandler

› MethodImplementationAspect› OnInvoke

› CompositionAspect› CreateImplementationObject

Aspect- Typen

Page 37: 2011-06-27 - AOP - .NET User Group Rhein Neckar

AOP

Bildnachweise

Ausgewä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.com