• Share
  • Email
  • Embed
  • Like
  • Save
  • Private Content
2011-06-27 - AOP - .NET User Group Rhein Neckar
 

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

on

  • 2,352 views

 

Statistics

Views

Total Views
2,352
Views on SlideShare
1,603
Embed Views
749

Actions

Likes
0
Downloads
16
Comments
0

3 Embeds 749

http://blog.johanneshoppe.de 742
url_unknown 6
http://translate.googleusercontent.com 1

Accessibility

Categories

Upload Details

Uploaded via as Microsoft PowerPoint

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

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

    • AspektOrientierteProgrammierungmit .NET
      Eine praktische Einführung
      27.06.2011
      Dipl.-Inf. (FH) Johannes Hoppe
    • Johannes Hoppe
      ASP.NET MVC Webentwickler
      www.johanneshoppe.de
    • 01
      Architektur und Patterns
    • Patterns
      Entwurfsmuster
      ==
      unser täglicher Job
    • Beispiel
    • Aber…
    • Business Code
      publicclassCustomerProcesses
      {
      publicvoid 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;
      }
      }
    • Business Code
      + Logging
      internalclassCustomerProcesses
      {
      privatestaticreadonlyTraceSource trace =
      newTraceSource( typeof (CustomerProcesses).FullName );
       
      publicvoid 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;
      }  
      }
      }
    • Business Code
      internalclassCustomerProcesses
      {
      privatestaticreadonlyTraceSource trace =
      newTraceSource(typeof(CustomerProcesses).FullName);
       
      publicvoid RentBook(int bookId, int customerId)
      {
      if (bookId <= 0) thrownewArgumentOutOfRangeException("bookId");
      if (customerId <= 0) thrownewArgumentOutOfRangeException("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
    • Business Code
      + Logging+ Transaktionen
      + Vorbedingungen
      internalclassCustomerProcesses
      {
      privatestaticreadonlyTraceSource trace =
      newTraceSource(typeof(CustomerProcesses).FullName);
       
      publicvoid RentBook(int bookId, int customerId)
      {
      if (bookId <= 0) thrownewArgumentOutOfRangeException("bookId");
      if (customerId <= 0) thrownewArgumentOutOfRangeException("customerId");
       
      trace.TraceInformation(
      "Entering CustomerProcesses.CreateCustomer( bookId = {0}, customerId = {1} )“, bookId, customerId);
       
      try
      {
      for (int i = 0; ; i++)
      {
      try
      {
      using (var ts = newTransactionScope())
      {
      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;
      }
      }
      }
    • Business Code
      + Logging+ Transaktionen
      + Vorbedingungen + Exception Handling
      internalclassCustomerProcesses
      {
      privatestaticreadonlyTraceSource trace =
      newTraceSource(typeof(CustomerProcesses).FullName);
       
      publicvoid RentBook(int bookId, int customerId)
      {
      if (bookId <= 0) thrownewArgumentOutOfRangeException("bookId");
      if (customerId <= 0) thrownewArgumentOutOfRangeException("customerId");
       
      try
      {
      trace.TraceInformation(
      "Entering CustomerProcesses.CreateCustomer( bookId = {0}, customerId = {1} )",
      bookId, customerId );
       
      try
      {
      for ( int i = 0;; i++ )
      {
      try
      {
      using ( var ts = newTransactionScope() )
      {
      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;
      }
      }
      }
    • Business Code
      + Logging+ Transaktionen
      + Vorbedingungen + Exception Handling
      + Feature X
      + Feature Y
      + Feature Z
      + …
    • Kern-funktionalitäten
      (Core Concerns)
      SeperationofConcerns
    • VS
    • VS
      Nicht-Funktionale Anforderungen(CrosscuttingConcerns)
    • Cross-CuttingConcerns
      Data Binding
      Thread Sync
      Caching
      Validation

      Security
      Exception Handling
      Tracing
      Monitoring
      Transaction
    • OOP
      OOP+ AOP
    • Spring.NET
      Castle
      MS Unity
      PostSharp
      LinFu
      Build-Time
      Run-Time
      Hybrid
    • Erfolgt zur Laufzeit
      Code bleibt unverändert
      Aufruf wird über Proxy umgeleitet
      Zur Laufzeit keine Änderungen
      Aufruf wird über Proxyumgeleitet
      Aspekte zur Laufzeitkonfigurierbar
      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
      Build-Time: “Statisch”
      Run-Time: “Dynamisch”
    • 02
      Live Coding
    • Logging
      LogTimeAspect
      webnoteaop.codeplex.com
    • Exceptions
      ConvertExceptionAspect
      webnoteaop.codeplex.com
    • Validierung
      ValidationGuardAspect
      webnoteaop.codeplex.com
    • Caching
      SimpleCacheAspect
      webnoteaop.codeplex.com
    • 03
      AOP 1 x 1
    • AspectJ Begriffe
      Join Point
      Pointcut
      Advice
      Aspect
    • AspectJ Begriffe
      Join Point
      Pointcut
      Advice
      Aspect
    • IL Code Vorher
      [LogTimeAspect]
      publicActionResult Index()
      {
      IEnumerable<NoteWithCategories> notes =
      this.WebNoteService.ReadAll();
      return View(notes);
      }
    • IL Code Nachher
      publicActionResult 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;
      }
    • OriginaleMethode
      Aspect Klasse
      OnEntry
      try{}
      catch (Exception e){}finally{}
      Method Body
      OnSuccess
      OnException
      OnExit
      : OnMethodBoundaryAspect
    • Links
      Spring.NET
      springframework.net
      Castle
      castleproject.org
      Unity
      unity.codeplex.com
      PostSharp
      sharpcrafters.com
      Demo Download
      webnoteaop.codeplex.com
    • FRAGEN?
    • Vielen Dank!
      Johannes Hoppe
    • Aspect- Typen
      MethodBoundaryAspect
      OnEntry
      OnSuccess
      OnException
      OnExit
      OnExceptionAspect
      OnException
      MethodInterceptionAspect
      OnInvoke
      LocationInterceptionAspect
      OnGetValue
      OnSetValue
      EventInterceptionAspect
      OnAddHandler
      OnRemoveHandler
      OnInvokeHandler
      MethodImplementationAspect
      OnInvoke
      CompositionAspect
      CreateImplementationObject
    • Bildnachweise
      Ausgewählter Ordner © Spectral-Design – Fotolia.com
      Warnhinweis-Schild © Sascha Tiebel – Fotolia.com
      Liste abhaken © Dirk Schumann – Fotolia.com
      3D rendering of an architecture model 2 © Franck Boston – Fotolia.com
      Healthcare © ArtmannWitte – Fotolia.com
      Stressed businessman © Selecstock – Fotolia.com
    • Farben Primär
    • Farben Code