+ All Categories
Home > Technology > 2012-04-12 - AOP .NET UserGroup Niederrhein

2012-04-12 - AOP .NET UserGroup Niederrhein

Date post: 29-Nov-2014
Category:
Upload: johannes-hoppe
View: 2,699 times
Download: 0 times
Share this document with a friend
Description:
 
42
12.04.2012 Dipl.-Inf. (FH) Johannes Hoppe AOP mit .NET
Transcript
Page 1: 2012-04-12 - AOP .NET UserGroup Niederrhein

12.04.2012

Dipl.-Inf. (FH) Johannes Hoppe

AOP mit .NET

Page 2: 2012-04-12 - AOP .NET UserGroup Niederrhein

Johannes Hoppe ASP.NET MVC Webentwickler

www.johanneshoppe.de

Page 3: 2012-04-12 - AOP .NET UserGroup Niederrhein

Architektur und Patterns

01

Page 4: 2012-04-12 - AOP .NET UserGroup Niederrhein

Patterns software craftsmanship

Page 5: 2012-04-12 - AOP .NET UserGroup Niederrhein

Business 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 6: 2012-04-12 - AOP .NET UserGroup Niederrhein

Business Code

Page 7: 2012-04-12 - AOP .NET UserGroup Niederrhein
Page 8: 2012-04-12 - AOP .NET UserGroup Niederrhein

Business 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 9: 2012-04-12 - AOP .NET UserGroup Niederrhein

+ Logging

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

}

}

}

Page 10: 2012-04-12 - AOP .NET UserGroup Niederrhein

+ Logging

+ Vorbedingungen

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

}

}

}

Page 11: 2012-04-12 - AOP .NET UserGroup Niederrhein

Business 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 12: 2012-04-12 - AOP .NET UserGroup Niederrhein

Business 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 13: 2012-04-12 - AOP .NET UserGroup Niederrhein

Business Code

+ Logging + Transaktionen

+ Vorbedingungen + Exception Handling

+ Feature X

+ Feature Y

+ Feature Z

+ …

Page 14: 2012-04-12 - AOP .NET UserGroup Niederrhein

Kern-

funktionalitäten (Core Concerns)

Seperation

of Concerns

Page 15: 2012-04-12 - AOP .NET UserGroup Niederrhein

VS

Page 16: 2012-04-12 - AOP .NET UserGroup Niederrhein

Nicht-

Funktionale

Anforderungen (Crosscutting Concerns)

VS

Page 17: 2012-04-12 - AOP .NET UserGroup Niederrhein

Security

Exception Handling

Tracing

Monitoring

Transaction

Data Binding

Thread Sync

Caching

Validation

Cross-Cutting Concerns

Page 18: 2012-04-12 - AOP .NET UserGroup Niederrhein

OOP

OOP

+ AOP

Page 19: 2012-04-12 - AOP .NET UserGroup Niederrhein

Build-Time Run-Time Hybrid

PostSharp

Spring.NET

Castle

MS Unity LinFu

Page 20: 2012-04-12 - AOP .NET UserGroup Niederrhein

Erfolgt bei Kompilierung

Code wird direkt verändert

Zur Laufzeit keine Änderungen

Auch auf Properties, Felder,

Events anwendbar

Keine Interfaces erforderlich

Erfolgt zur Laufzeit

Code bleibt unverändert

Zur Laufzeit Änderungen möglich

Aufruf wird über Proxy

umgeleitet

idR. Interfaces erforderlich (Proxy)

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

Page 21: 2012-04-12 - AOP .NET UserGroup Niederrhein

Live Coding

02

Page 22: 2012-04-12 - AOP .NET UserGroup Niederrhein
Page 23: 2012-04-12 - AOP .NET UserGroup Niederrhein

Logging LogTimeAspect

webnoteaop.codeplex.com

Page 24: 2012-04-12 - AOP .NET UserGroup Niederrhein

Exceptions ConvertExceptionAspect

webnoteaop.codeplex.com

Page 25: 2012-04-12 - AOP .NET UserGroup Niederrhein

Validierung ValidationGuardAspect

webnoteaop.codeplex.com

Page 26: 2012-04-12 - AOP .NET UserGroup Niederrhein

Caching SimpleCacheAspect

webnoteaop.codeplex.com

Page 27: 2012-04-12 - AOP .NET UserGroup Niederrhein
Page 28: 2012-04-12 - AOP .NET UserGroup Niederrhein

AOP 1 x 1

03

Page 29: 2012-04-12 - AOP .NET UserGroup Niederrhein

AspectJ Begriffe

Join Point

Pointcut

Advice

Aspect

Page 30: 2012-04-12 - AOP .NET UserGroup Niederrhein

AspectJ Begriffe

Join Point

Pointcut

Advice

Aspect

Page 31: 2012-04-12 - AOP .NET UserGroup Niederrhein

IL Code Vorher

[LogTimeAspect]

public ActionResult Index()

{

IEnumerable<NoteWithCategories> notes =

this.WebNoteService.ReadAll();

return View(notes);

}

Page 32: 2012-04-12 - AOP .NET UserGroup Niederrhein

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;

}

Page 33: 2012-04-12 - AOP .NET UserGroup Niederrhein

: OnMethodBoundaryAspect

try { } catch (Exception e) { } finally { }

OnEntry

OnSuccess

OnException

OnExit

Originale Methode Aspekt Klasse

Method Body

Page 34: 2012-04-12 - AOP .NET UserGroup Niederrhein

Installation

04

Page 35: 2012-04-12 - AOP .NET UserGroup Niederrhein

www.sharpcrafters.com/postsharp/download

Page 36: 2012-04-12 - AOP .NET UserGroup Niederrhein

nuget http://nuget.org/packages/PostSharp

Page 38: 2012-04-12 - AOP .NET UserGroup Niederrhein

FRAGEN?

Page 39: 2012-04-12 - AOP .NET UserGroup Niederrhein

Bis bald › 10.05.2012 – .NET UG Karlsruhe: NoSQL

› 14.05.2012 – .NET Developer Conference (DDC)

.Nürnberg: NoSQL

Page 40: 2012-04-12 - AOP .NET UserGroup Niederrhein

Vielen Dank!

Page 41: 2012-04-12 - AOP .NET UserGroup Niederrhein

› MethodBoundaryAspect

› OnEntry

› OnSuccess

› OnException

› OnExit

› OnExceptionAspect

› OnException

› MethodInterceptionAspect

› OnInvoke

› LocationInterceptionAspect

› OnGetValue

› OnSetValue

› EventInterceptionAspect

› OnAddHandler

› OnRemoveHandler

› OnInvokeHandler

› MethodImplementationAspect

› OnInvoke

› CompositionAspect

› CreateImplementationObject

Primitive Aspekt-Typen

Page 42: 2012-04-12 - AOP .NET UserGroup Niederrhein

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

Funny cartoon boss © artenot – Fotolia.com


Recommended