2012-04-12 - aop .net usergroup niederrhein
DESCRIPTION
TRANSCRIPT
![Page 1: 2012-04-12 - AOP .NET UserGroup Niederrhein](https://reader036.vdocuments.pub/reader036/viewer/2022081413/547b5af0b479599f098b4d5d/html5/thumbnails/1.jpg)
12.04.2012
Dipl.-Inf. (FH) Johannes Hoppe
AOP mit .NET
![Page 3: 2012-04-12 - AOP .NET UserGroup Niederrhein](https://reader036.vdocuments.pub/reader036/viewer/2022081413/547b5af0b479599f098b4d5d/html5/thumbnails/3.jpg)
Architektur und Patterns
01
![Page 4: 2012-04-12 - AOP .NET UserGroup Niederrhein](https://reader036.vdocuments.pub/reader036/viewer/2022081413/547b5af0b479599f098b4d5d/html5/thumbnails/4.jpg)
Patterns software craftsmanship
![Page 5: 2012-04-12 - AOP .NET UserGroup Niederrhein](https://reader036.vdocuments.pub/reader036/viewer/2022081413/547b5af0b479599f098b4d5d/html5/thumbnails/5.jpg)
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](https://reader036.vdocuments.pub/reader036/viewer/2022081413/547b5af0b479599f098b4d5d/html5/thumbnails/6.jpg)
Business Code
![Page 7: 2012-04-12 - AOP .NET UserGroup Niederrhein](https://reader036.vdocuments.pub/reader036/viewer/2022081413/547b5af0b479599f098b4d5d/html5/thumbnails/7.jpg)
![Page 8: 2012-04-12 - AOP .NET UserGroup Niederrhein](https://reader036.vdocuments.pub/reader036/viewer/2022081413/547b5af0b479599f098b4d5d/html5/thumbnails/8.jpg)
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](https://reader036.vdocuments.pub/reader036/viewer/2022081413/547b5af0b479599f098b4d5d/html5/thumbnails/9.jpg)
+ 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](https://reader036.vdocuments.pub/reader036/viewer/2022081413/547b5af0b479599f098b4d5d/html5/thumbnails/10.jpg)
+ 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](https://reader036.vdocuments.pub/reader036/viewer/2022081413/547b5af0b479599f098b4d5d/html5/thumbnails/11.jpg)
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](https://reader036.vdocuments.pub/reader036/viewer/2022081413/547b5af0b479599f098b4d5d/html5/thumbnails/12.jpg)
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](https://reader036.vdocuments.pub/reader036/viewer/2022081413/547b5af0b479599f098b4d5d/html5/thumbnails/13.jpg)
Business Code
+ Logging + Transaktionen
+ Vorbedingungen + Exception Handling
+ Feature X
+ Feature Y
+ Feature Z
+ …
![Page 14: 2012-04-12 - AOP .NET UserGroup Niederrhein](https://reader036.vdocuments.pub/reader036/viewer/2022081413/547b5af0b479599f098b4d5d/html5/thumbnails/14.jpg)
Kern-
funktionalitäten (Core Concerns)
Seperation
of Concerns
![Page 15: 2012-04-12 - AOP .NET UserGroup Niederrhein](https://reader036.vdocuments.pub/reader036/viewer/2022081413/547b5af0b479599f098b4d5d/html5/thumbnails/15.jpg)
VS
![Page 16: 2012-04-12 - AOP .NET UserGroup Niederrhein](https://reader036.vdocuments.pub/reader036/viewer/2022081413/547b5af0b479599f098b4d5d/html5/thumbnails/16.jpg)
Nicht-
Funktionale
Anforderungen (Crosscutting Concerns)
VS
![Page 17: 2012-04-12 - AOP .NET UserGroup Niederrhein](https://reader036.vdocuments.pub/reader036/viewer/2022081413/547b5af0b479599f098b4d5d/html5/thumbnails/17.jpg)
Security
Exception Handling
Tracing
Monitoring
Transaction
Data Binding
Thread Sync
Caching
Validation
…
Cross-Cutting Concerns
![Page 18: 2012-04-12 - AOP .NET UserGroup Niederrhein](https://reader036.vdocuments.pub/reader036/viewer/2022081413/547b5af0b479599f098b4d5d/html5/thumbnails/18.jpg)
OOP
OOP
+ AOP
![Page 19: 2012-04-12 - AOP .NET UserGroup Niederrhein](https://reader036.vdocuments.pub/reader036/viewer/2022081413/547b5af0b479599f098b4d5d/html5/thumbnails/19.jpg)
Build-Time Run-Time Hybrid
PostSharp
Spring.NET
Castle
MS Unity LinFu
![Page 20: 2012-04-12 - AOP .NET UserGroup Niederrhein](https://reader036.vdocuments.pub/reader036/viewer/2022081413/547b5af0b479599f098b4d5d/html5/thumbnails/20.jpg)
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](https://reader036.vdocuments.pub/reader036/viewer/2022081413/547b5af0b479599f098b4d5d/html5/thumbnails/21.jpg)
Live Coding
02
![Page 22: 2012-04-12 - AOP .NET UserGroup Niederrhein](https://reader036.vdocuments.pub/reader036/viewer/2022081413/547b5af0b479599f098b4d5d/html5/thumbnails/22.jpg)
![Page 27: 2012-04-12 - AOP .NET UserGroup Niederrhein](https://reader036.vdocuments.pub/reader036/viewer/2022081413/547b5af0b479599f098b4d5d/html5/thumbnails/27.jpg)
![Page 28: 2012-04-12 - AOP .NET UserGroup Niederrhein](https://reader036.vdocuments.pub/reader036/viewer/2022081413/547b5af0b479599f098b4d5d/html5/thumbnails/28.jpg)
AOP 1 x 1
03
![Page 29: 2012-04-12 - AOP .NET UserGroup Niederrhein](https://reader036.vdocuments.pub/reader036/viewer/2022081413/547b5af0b479599f098b4d5d/html5/thumbnails/29.jpg)
AspectJ Begriffe
Join Point
Pointcut
Advice
Aspect
![Page 30: 2012-04-12 - AOP .NET UserGroup Niederrhein](https://reader036.vdocuments.pub/reader036/viewer/2022081413/547b5af0b479599f098b4d5d/html5/thumbnails/30.jpg)
AspectJ Begriffe
Join Point
Pointcut
Advice
Aspect
![Page 31: 2012-04-12 - AOP .NET UserGroup Niederrhein](https://reader036.vdocuments.pub/reader036/viewer/2022081413/547b5af0b479599f098b4d5d/html5/thumbnails/31.jpg)
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](https://reader036.vdocuments.pub/reader036/viewer/2022081413/547b5af0b479599f098b4d5d/html5/thumbnails/32.jpg)
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](https://reader036.vdocuments.pub/reader036/viewer/2022081413/547b5af0b479599f098b4d5d/html5/thumbnails/33.jpg)
: 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](https://reader036.vdocuments.pub/reader036/viewer/2022081413/547b5af0b479599f098b4d5d/html5/thumbnails/34.jpg)
Installation
04
![Page 36: 2012-04-12 - AOP .NET UserGroup Niederrhein](https://reader036.vdocuments.pub/reader036/viewer/2022081413/547b5af0b479599f098b4d5d/html5/thumbnails/36.jpg)
nuget http://nuget.org/packages/PostSharp
![Page 37: 2012-04-12 - AOP .NET UserGroup Niederrhein](https://reader036.vdocuments.pub/reader036/viewer/2022081413/547b5af0b479599f098b4d5d/html5/thumbnails/37.jpg)
Spring.NET springframework.net
Castle castleproject.org
Unity unity.codeplex.com
PostSharp sharpcrafters.com
Demo Download webnoteaop.codeplex.com
![Page 38: 2012-04-12 - AOP .NET UserGroup Niederrhein](https://reader036.vdocuments.pub/reader036/viewer/2022081413/547b5af0b479599f098b4d5d/html5/thumbnails/38.jpg)
FRAGEN?
![Page 39: 2012-04-12 - AOP .NET UserGroup Niederrhein](https://reader036.vdocuments.pub/reader036/viewer/2022081413/547b5af0b479599f098b4d5d/html5/thumbnails/39.jpg)
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](https://reader036.vdocuments.pub/reader036/viewer/2022081413/547b5af0b479599f098b4d5d/html5/thumbnails/40.jpg)
Vielen Dank!
![Page 41: 2012-04-12 - AOP .NET UserGroup Niederrhein](https://reader036.vdocuments.pub/reader036/viewer/2022081413/547b5af0b479599f098b4d5d/html5/thumbnails/41.jpg)
› 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](https://reader036.vdocuments.pub/reader036/viewer/2022081413/547b5af0b479599f098b4d5d/html5/thumbnails/42.jpg)
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