© siemens ag, michael stal 1 c o r p o r a t e t e c h n o l o g y software & engineering...
Post on 21-Dec-2015
214 views
TRANSCRIPT
© Siemens AG, Michael Stal11
C
O R
P O
R A
T E
T
E C
H N
O L
O G
Y
Software &Engineering Architecture
Spring.NETIntroduction and Overview
© Siemens AG, Michael Stal22
C
O R
P O
R A
T E
T
E C
H N
O L
O G
Y
Software &Engineering Architecture
Content
1. Motivation
2. Dependency Injection Basics
3. Spring.NET Fundamentals
4. Spring.NET AOP
5. Further Ingredients
6. Summary
7. References
© Siemens AG, Michael Stal33
C
O R
P O
R A
T E
T
E C
H N
O L
O G
Y
Software &Engineering Architecture
Motivation
• Spring.NET is• an application framework for
buidling Enterprise .NET applications
• an IoC Container (Inversion of Control) that manages and injects dependencies on behalf of developers (DI = Dependency Injection)
• resembles the Java version but is not a naive port
• version 1.0 introduces DI and AOP (Aspect-Oriented Programming). Upcoming versions will add ASP.NET, Persistence, Remoting support
© Siemens AG, Michael Stal44
C
O R
P O
R A
T E
T
E C
H N
O L
O G
Y
Software &Engineering Architecture
Dependency Injection Explained (0)
What is a Dependency?
A Dependency between a source class X and a target class Y occurs when each
instance X needs an instance of Y!
But what‘s the problem?
The problem is that X needs to know how to create the Y instance!
© Siemens AG, Michael Stal55
C
O R
P O
R A
T E
T
E C
H N
O L
O G
Y
Software &Engineering Architecture
Dependency Injection Explained (1)
• Consider the following example:
• Liability:• A depends on way to create or otherwise obtain a B instance
public class A {public B cb; // A depends on Bpublic A() { cb = get_B_Object(...); }...
}public class B { ... }public class Container {
public A createA() {return new A();
}}
Dependency resolved by A!
© Siemens AG, Michael Stal66
C
O R
P O
R A
T E
T
E C
H N
O L
O G
Y
Software &Engineering Architecture
Dependency Injection Explained (2)
• Other possibilities include setter injection and constructor injection (A does not depend on how Bs are created):
public class A {protected B b1; // A depends on Bprotected B b2;public A(B b1) { this.b1 = b1; } // dependency injectionpublic B B2 { set { this.b2 = value; } } // dependency injection...
}public class B { ... }public class IoCContainer {
public A createA() {B b1 = get_B_Object(...);A a = new A(b1); // constructor injectionB b2 = get_B_Object(...);a.B2 = b2; // setter aka property injectionreturn a;
}}
© Siemens AG, Michael Stal77
C
O R
P O
R A
T E
T
E C
H N
O L
O G
Y
Software &Engineering Architecture
Dependency Injection Explained (3)
• But how does the Container know which dependencies to inject?
class A {
protected B _b;
public B b {
set { b = value;}
}
}
<object id = „a“ type=„A“>
<set-prop ref=„b“>
</object>
<object id = „b“ type = „B“/>
Actual Implementation
Configuration of Dependencies
IoC Container
© Siemens AG, Michael Stal88
C
O R
P O
R A
T E
T
E C
H N
O L
O G
Y
Software &Engineering Architecture
Dependency Injection Explained (4)
• Yet another possibility is field injection (reflection-based):
• But field injection is generally considered bad design!
public class A {public B cb;public A() { ... }...
}public class B { ... }public class IoCContainer {
public A createA() {A a = new A();a.b = get_B_Object(...);return a;
}}
© Siemens AG, Michael Stal99
C
O R
P O
R A
T E
T
E C
H N
O L
O G
Y
Software &Engineering Architecture
IoC Containers for .NET
• PicoContainer.NET: lightweight and highly embeddable IoC container
• StructureMap: lightweight Inversion of Control (IoC) Container written in C#; can improve the architectural qualities of .NET apps by reducing the mechanical costs of good design techniques
• Castle: Tools for application development including small IoC container
• Spring.NET: full featured IoC container (port of Java version)
© Siemens AG, Michael Stal1010
C
O R
P O
R A
T E
T
E C
H N
O L
O G
Y
Software &Engineering Architecture
Spring.NET: General Constituents
• Spring Core: base library for DI
• Spring AOP: enriches base container with AOP concepts
• Spring Web extends ASP.NET with DI, bidirectional data binding
• Spring Services enables the exposal of PONOs (Plain Old .NET Objects) as Web/Enterprise/Remote services
• Spring Data provides a Data Access Layer. It also eases ADO.NET
• Spring.ORM provides integration of popular persistence frameworks
© Siemens AG, Michael Stal1111
C
O R
P O
R A
T E
T
E C
H N
O L
O G
Y
Software &Engineering Architecture
Introduction Example (1)
• Let us start with a Practice-First approach. An object exampleObject that depends on other objects:
public class ExampleObject {
private AnotherObject objectOne; // dependencies
private YetAnotherObject objectTwo;
private int i;
public AnotherObject ObjectOne {
set { this.objectOne = value; }
}
public YetAnotherObject ObjectTwo {
set { this.objectTwo = value; }
}
public int IntegerProperty {
set { this.i = value; }
}
}
© Siemens AG, Michael Stal1212
C
O R
P O
R A
T E
T
E C
H N
O L
O G
Y
Software &Engineering Architecture
Introduction Example (2)
• The configuration tells Spring.NET how objects depend on each other:
<object id="exampleObject" type="Examples.ExampleObject, ExamplesLibrary">
<property name="objectOne" ref="anotherExampleObject"/>
<property name="objectTwo" ref="yetAnotherObject"/>
<property name="IntegerProperty" value="1"/>
</object>
<object id="anotherExampleObject" type="Examples.AnotherObject, ExamplesLibrary"/>
<object id="yetAnotherObject" type="Examples.YetAnotherObject, ExamplesLibrary"/>
Object name Object type: namespace path + class, assembly
Properties referring to other objects: often called dependencies or collaborators
© Siemens AG, Michael Stal1313
C
O R
P O
R A
T E
T
E C
H N
O L
O G
Y
Software &Engineering Architecture
On Objects and Factories
• Spring.NET attempts • to reduce dependencies between objects • to act as non-invasive as possible: almost no dependencies of
application from Spring.NET
• IObjectFactory is• the actual container that instantiates, manages and configures
collaborating objects.• represented by the interface IObjectFactory which has many
implementations (such as XMLObjectFactory).• can be instantiated using new-operator or, even better, via configuration
file. Example:
IResource input = new FileSystemResource ("objects.xml");
IObjectFactory factory = new XmlObjectFactory(input);
• IApplicationContext denotes a superset of IObjectFactory.
© Siemens AG, Michael Stal1414
C
O R
P O
R A
T E
T
E C
H N
O L
O G
Y
Software &Engineering Architecture
Configuration
• Preferred way to create Object Factories and Application contexts is via configuration:
<configuration>
<configSections>
<sectionGroup name="spring">
<section name="context" type="Spring.Context.Support.ContextHandler, Spring.Core"/>
<section name="objects" type="Spring.Context.Support.DefaultSectionHandler, Spring.Core" />
</sectionGroup>
</configSections>
<spring>
<context>
<resource uri="config://spring/objects"/>
</context>
<objects>
...
</objects>
</spring>
</configuration>
Handlers used for Spring configuration section
Where to find object configuration, e.g. file, assembly, config
Configuration of Spring managed objects
© Siemens AG, Michael Stal1515
C
O R
P O
R A
T E
T
E C
H N
O L
O G
Y
Software &Engineering Architecture
Configuration cont‘d
• Now instantiating and using ObjectFactory or ApplicationContext is simple:
• Factories provide different methods:
IApplicationContext ctx = ContextRegistry.GetContext();
MyPerson person = (MyPerson) ctx.GetObject(“myPerson");
ID that should appear in object configuration
IResource input = new FileSystemResource ("objects.xml");
XmlObjectFactory factory = new XmlObjectFactory(input);
object foo = factory.GetObject ("foo"); // gets the object defined as 'foo'
object bar = factory ["bar"]; // same thing, just using the indexer
© Siemens AG, Michael Stal1616
C
O R
P O
R A
T E
T
E C
H N
O L
O G
Y
Software &Engineering Architecture
Object Creation
• In most cases, objects are created using constructors:
• Another possibility is using a static factory method of a factory class:
• Or as the result of a non-static factory method of another object:
<object id=“myObj" type=“MyNS.MyObject, MyLibrary"/>
<object id=“myObj“ type=“MyNS.MyFactory, MyLibrary"
factory-method="CreateInstance"/>
Type of factory not of created object!
<object id=“MyFactory" type="..."/>
<object id=“MyObj"
factory-method="CreateInstance"
factory-object=“MyFactory"/>
© Siemens AG, Michael Stal1717
C
O R
P O
R A
T E
T
E C
H N
O L
O G
Y
Software &Engineering Architecture
Object Lifecycle
• Objects per default created as singletons• object‘s id / name refers always to same instance• lifecycle controlled by Spring
• Other possibility: prototype (non-singleton)• new object created for each separate access access to id / name• lifecycle controlled by requester, not by Spring factory
<object id=“myObj" type=“MyNS.MyObject, MyLibrary"
singleton="false"/>
<object name="yetAnotherExample" type=“MyNS.ExampleObjectTwo, MyLibrary"
singleton="true"/>
© Siemens AG, Michael Stal1818
C
O R
P O
R A
T E
T
E C
H N
O L
O G
Y
Software &Engineering Architecture
Types of Dependency Injection
• Spring .NET supports Property and Constructor Injection:
• constructor-arg also applicable for factory objects or static factory methods
<object id=“MyObject" type=“MyNS.MixedIocObject, MyLibrary">
<constructor-arg name="objectOne" ref="anotherExampleObject"/>
</object>
<object id="anotherExampleObject" type=“MyNS.Class2, MyLibrary"/>
public class MixedIocObject {
private Class2 objectOne;
public MixedIocObject (Class2 obj) {
this.objectOne = obj;
}
}
© Siemens AG, Michael Stal1919
C
O R
P O
R A
T E
T
E C
H N
O L
O G
Y
Software &Engineering Architecture
Ordering of Constructor Arguments
• constructor-arg elements are unordered. Thus, use index:
• or names:
<object name=“myObj" type=“MyNS.MYObject, NyApp">
<constructor-arg index="0" value="7500000"/>
<constructor-arg index="1" value="42"/>
</object>
<object name=“myObj" type=“MyNS.MYObject, NyApp">
<constructor-arg name="years" value="7500000"/>
<constructor-arg name="ultimateAnswer" value="42"/>
</object>
© Siemens AG, Michael Stal2020
C
O R
P O
R A
T E
T
E C
H N
O L
O G
Y
Software &Engineering Architecture
Setting Complex Values
• Setting complex value types list, set, name-values, dictionaries are supported:
• Inlining:
• Additional Remarks: • Spring uses built-in TypeConverters to convert from String to target type. It is easy
to define your own custom converters.• Special Spring.NET configuration element <null> to set values to null.• Other forms of references to collaborators available: ref local, ref parent
<property name="SomeList">
<list>
<value> string </value>
<ref object="myConnection"/>
</list>
</property>
<object id="outer" type="...">
<property name="target">
<object type="ExampleApp.Answers, ExampleApp">
<property name=“answer" value=“42"/>
</object>
</property>
</object>
© Siemens AG, Michael Stal2121
C
O R
P O
R A
T E
T
E C
H N
O L
O G
Y
Software &Engineering Architecture
IFactoryObject
• Interface implemented by objects that are themselves factories:
• Object GetObject(): returns instance created by factory• Bool isSingleton: true if factory object returns singletons• Type ObjectType: object type returned by GetObject() or null if
not known in advance
• Examples on next slides
© Siemens AG, Michael Stal2222
C
O R
P O
R A
T E
T
E C
H N
O L
O G
Y
Software &Engineering Architecture
Advanced Dependency Injection
• It is possible to use other object‘s properties, fields or methods for setting properties.
• Spring.NET uses FactoryObjects for this purpose.
• The object theAge is instantiated using the person object‘s embedded spouse.age property
<object name="person" type="Spring.Objects.TestObject, Spring.Core.Tests">
<property name="spouse">
<object type="Spring.Objects.TestObject, Spring.Core.Tests">
<property name="age" value="21"/>
</object>
</property>
</object>
<object name="theAge" type="Spring.Objects.Factory.Config.PropertyRetrievingFactoryObject, Spring.Core">
<property name="TargetObject" ref="person"/>
<property name="TargetProperty" value="spouse.age"/>
</object>
© Siemens AG, Michael Stal2323
C
O R
P O
R A
T E
T
E C
H N
O L
O G
Y
Software &Engineering Architecture
Advanced Dependency Injection (cont‘d)
• An example for method-based injection:
• This object will be created by calling the method GetInstance (TargetMethod) of a MyClassFactory object (TargetType) using the specified arguments (Arguments)
• Object can then be used for dependency injection
<object id="myObject" type="Spring.Objects.Factory.Config.MethodInvokingFactoryObject, Spring.Core">
<property name="TargetType" value="Whatever.MyClassFactory, MyAssembly"/>
<property name="TargetMethod" value="GetInstance"/>
<!-- the ordering of arguments is significant -->
<property name="Arguments">
<list>
<value>1st</value>
<value>2nd</value>
<value>and 3rd arguments</value>
</list>
</property>
</object>
© Siemens AG, Michael Stal2424
C
O R
P O
R A
T E
T
E C
H N
O L
O G
Y
Software &Engineering Architecture
Log4Net
• Another example for a IFactoryObject implementation is log4Net
<objects xmlns="http://www.springframework.net"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.net
http://www.springframework.net/xsd/spring-objects.xsd" >
<object name="daoLogger"
type="Spring.Objects.Factory.Config.Log4NetFactoryObject, Spring.Core">
<property name="logName" value="DAOLogger"/>
</object>
<object name="productDao" type="PropPlayApp.SimpleProductDao, PropPlayApp ">
<property name="maxResults" value="100"/>
<property name="dbConnection" ref="myConnection"/>
<property name="log" ref="daoLogger"/>
</object>
<object name="myConnection" type="System.Data.Odbc.OdbcConnection,
System.Data">
<property name="connectionstring“
value="dsn=MyDSN;uid=sa;pwd=myPassword;"/>
</object>
</objects>
© Siemens AG, Michael Stal2525
C
O R
P O
R A
T E
T
E C
H N
O L
O G
Y
Software &Engineering Architecture
Lifecycle Callbacks
• Spring container can notify objects when they are initialized or destroyed:
• Clasa may instead implement interfaces (IDisposable, IInitializingObject) but then dependencies on Spring.NET container are introduced
<object id="exampleInitObject" type="Examples.ExampleObject" init-method="init“ destroy-method=“cleanup”/>
public class ExampleObject {
public void Init() {
// do some initialization work
}
public void cleanup() {
// do some destruction work
}
}
© Siemens AG, Michael Stal2626
C
O R
P O
R A
T E
T
E C
H N
O L
O G
Y
Software &Engineering Architecture
Some Additional Capabilities
• Autowiring is another option: uses reflection to determine and resolve dependencies (no config required). Different types of autowiring possible. Usually, better not to use autowiring.
• For an object definition depends-on means: this object depends on other objects which should be initialized first.
• Objects can be defined with dependency checking modes ao that Spring.NET will try to find out if all properties of an object are defined.
• Aliasing possible:
• Object definitions might be abstract. Childs can inherit:
<alias name="fromName" alias="toName"/>
<object id=“parentObj“ abstract=“true”>
<property name="name" value="parent"/>
<property name="age" value="1"/>
</object>
<object id=“childObj" type=“...” parent=“parentObj" init-method="Initialize">
<property name="name" value="override"/>
</object>
© Siemens AG, Michael Stal2727
C
O R
P O
R A
T E
T
E C
H N
O L
O G
Y
Software &Engineering Architecture
Object(Factory)PostProcessors
• A very powerful feature of Spring.NET are ObjectPostProcessors and ObjectFactoryPostProcessors:
• ObjectPostProcessors • get invoked before and after object initialization
• can change object and return changed object to Spring
• for example used to wrap objects with proxies
• ObjectFactoryPostProcessors• Can change object factories / application contexts such as overwriting
configuration information or accessing it from another source
• Examples• PropertyPlaceHolderConfigurer• PropertyOverrideConfigurer
• Object(Factory)PostProcessors automatically detected by ApplicationContexts. Must be manually registered with ObjectFactories.
© Siemens AG, Michael Stal2828
C
O R
P O
R A
T E
T
E C
H N
O L
O G
Y
Software &Engineering Architecture
ApplicationContexts
• IApplicationContext objects superset of IObjectFactory objects
• Additional capabilities:• Automatic registration of Object(Factory)PostProcessors• Loading of hierarchical contexts• Access to localized ressources• Uniform access to ressources• Loosely Coupled Event Propagation
• Should be always preferred over plain object factories except for ressource-constrained environments
© Siemens AG, Michael Stal2929
C
O R
P O
R A
T E
T
E C
H N
O L
O G
Y
Software &Engineering Architecture
ApplicationContexts cont‘d
• Example Hierarchical Contexts:
• Example Resource Managers:
<spring>
<context>
<resource uri="assembly://MyAssembly/MyProject/root-objects.xml"/>
<context name="mySubContext">
<resource uri="file://objects.xml"/>
</context>
</context>
</spring>
IApplicationContex ctx = ContextRegistry.GetContext("mySubContext");
<object name="myResourceManager" type="Spring.Objects.Factory.Config.ResourceManagerFactoryObject, Spring.Core">
<property name="baseName">
<value>Spring.Examples.AppContext.MyResource</value>
</property>
<property name="assemblyName">
<value>Spring.Examples.AppContext</value>
</property>
</object> // C# code:
string msg = ctx.GetMessage("HelloMessage", new object[] {"Mr.",
"Anderson"},CultureInfo.CurrentCulture );
© Siemens AG, Michael Stal3030
C
O R
P O
R A
T E
T
E C
H N
O L
O G
Y
Software &Engineering Architecture
ApplicationContexts cont‘d
• Spring.NET application containers automatically register event publishers and send events to detected known subscribers
• Event reception by implementing IApplicationListerener interface
• Container itself also might send events such as when closing a context. Example code (lot of details omitted):
IApplicationContext ctx = ContextRegistry.GetContext();
MyEventPublisher publisher = (MyEventPublisher)ctx.GetObject("MyEventPublisher");
ctx.PublishEvents( publisher );
MyEventSubscriber subscriber = (MyEventSubscriber)ctx.GetObject("MyEventSubscriber");
ctx.Subscribe( subscriber, typeof(MyEventPublisher) );
© Siemens AG, Michael Stal3131
C
O R
P O
R A
T E
T
E C
H N
O L
O G
Y
Software &Engineering Architecture
Spring.NET AOP
• One of the key components of Spring.NET
• AOP Concepts:• Aspect: modularized cross-cutting concern applicable to multiple objects• Joinpoint: Execution point of a program such as a method invocation or
exception being thrown• Advice: aspect to be conducted when program is at a specific joinpoint.
Such as „before method o.m() is executed write information to log“• Pointcut: set of joinpoints specifying when advice should be executed• Advisor: pair consisting of pointcut plus advice• Introduction: Using Spring.NET AOP to mix-in functionality to objects• Target / advised object: object where joinpoint is contained and which
gets proxied by Spring.NET AOP• AOP Proxy: Dynamic procy created by Spring.NET including advice and
delegating to advised object• Weaving: process to produce an advised object
© Siemens AG, Michael Stal3232
C
O R
P O
R A
T E
T
E C
H N
O L
O G
Y
Software &Engineering Architecture
General Design Principle
IApplicationInterface
IApplicationInterface
AOP ProxyClient
IProxyInterface
Advised Object
Advice Advice Advice
1. Client retrieves application interface from proxy
2. Client invoked method on application interface
3. Proxy executes (chain of) advises on joinpoints and delegates invocation to advised object
© Siemens AG, Michael Stal3333
C
O R
P O
R A
T E
T
E C
H N
O L
O G
Y
Software &Engineering Architecture
Motivating Example
• Here is a command pattern implementation:
• We‘d like to log each call to the Execute() method on the console without touching our source code using an advice:
public interface ICommand {
void Execute();
}
public class ServiceCommand : ICommand {
public void Execute() {
Console.Out.WriteLine("Service implementation...");
}
}
public class ConsoleLoggingAroundAdvice : IMethodInterceptor {
public object Invoke(IMethodInvocation invocation) {
Console.Out.WriteLine(“calling method..."); ¶
object retv = invocation.Proceed(); · ¸
Console.Out.WriteLine(“method returned " + retv); ¹
return retv; º
}
}
© Siemens AG, Michael Stal3434
C
O R
P O
R A
T E
T
E C
H N
O L
O G
Y
Software &Engineering Architecture
Motivating Example cont‘d
• We have to tell Spring.NET about this intent:
• Object gets proxied
<object id="consoleLoggingAroundAdvice"
type="Spring.Examples.AopQuickStart.ConsoleLoggingAroundAdvice"/>
<object id="myServiceObject“ type="Spring.Aop.Framework.ProxyFactoryObject">
<property name="target">
<object id="myServiceObjectTarget"
type="Spring.Examples.AopQuickStart.ServiceCommand"/>
</property>
<property name="interceptorNames">
<list>
<value>consoleLoggingAroundAdvice</value>
</list>
</property>
</object>
© Siemens AG, Michael Stal3535
C
O R
P O
R A
T E
T
E C
H N
O L
O G
Y
Software &Engineering Architecture
Motivating Example cont‘d
• Now we can use advised object. Note, that actually we get the proxy not the target object:
ICommand command = (ICommand) ctx["myServiceObject"];
command.Execute();
© Siemens AG, Michael Stal3636
C
O R
P O
R A
T E
T
E C
H N
O L
O G
Y
Software &Engineering Architecture
Spring.NET AOP Fundamentals
• Pointcuts implement IPointCut:
• Static and dynamic pointcuts (IsRuntime==true) possible
• Dynamic pointcut example: control flow pointcut
public interface IPointcut {
ITypeFilter TypeFilter { get; }
IMethodMatcher MethodMatcher { get; }
}
// Does type match?
public interface ITypeFilter {
bool Matches(Type type);
}
// does method match?
public interface IMethodMatcher {
bool IsRuntime { get; }
bool Matches(MethodInfo method, Type targetType);
bool Matches(MethodInfo method, Type targetType, object[] args);
}
© Siemens AG, Michael Stal3737
C
O R
P O
R A
T E
T
E C
H N
O L
O G
Y
Software &Engineering Architecture
Pointcuts
• Pointcut operations: union, intersection
• Regular Expression Pointcut (methods starting with set..):
• Attribute Pointcut (all methods with a specific attribute):
<object id="settersAndAbsquatulatePointcut"
type="Spring.Aop.Support.SdkRegexpMethodPointcut, Spring.Aop">
<property name="patterns">
<list>
<value>.*set.*</value>
<value>.*absquatulate</value>
</list>
</property>
</object>
<object id="cachePointcut"
type="Spring.Aop.Support.AttributeMatchMethodPointcut, Spring.Aop">
<property name="Attribute" value="Spring.Attributes.CacheAttribute,
Spring.Core"/>
</object>
© Siemens AG, Michael Stal3838
C
O R
P O
R A
T E
T
E C
H N
O L
O G
Y
Software &Engineering Architecture
Pointcut Superclass
• Static Method Matcher:
• You may inherit from this class to implement your own pointcuts
• By the way, in the case you are wondering: In our introduction we used the default TruePointcut which maches for everything
public class TestStaticPointcut : StaticMethodMatcherPointcut {
public override bool Matches(MethodInfo method, Type targetType) {
// return true if custom criteria match
}
}
© Siemens AG, Michael Stal3939
C
O R
P O
R A
T E
T
E C
H N
O L
O G
Y
Software &Engineering Architecture
Advisors
• Advisors combine a pointcut with an advice
• Regular Expression Advisor:
• Attribute Advisor:
<object id="settersAndAbsquatulateAdvisor"
type="Spring.Aop.Support.RegexpMethodPointcutAdvisor, Spring.Aop">
<property name="advice">
<ref local="objectNameOfAopAllianceInterceptor"/>
</property>
<property name="patterns">
<list>
<value>.*set.*</value>
<value>.*absquatulate</value>
</list>
</property>
</object>
<object id="AspNetCacheAdvice" type="Spring.Aop.Support.AttributeMatchMethodPointcutAdvisor, Spring.Aop">
<property name="advice">
<object type="Aspect.AspNetCacheAdvice, Aspect"/>
</property>
<property name="attribute" value="Framework.AspNetCacheAttribute, Framework" />
</object>
© Siemens AG, Michael Stal4040
C
O R
P O
R A
T E
T
E C
H N
O L
O G
Y
Software &Engineering Architecture
Advices
• Advices lifecycle per-class or per-instance
• Interception Around Advice
• Intercepts method invocation
• Code must call Proceed() to delegate invocation to advised object
public class DebugInterceptor : IMethodInterceptor {
public object Invoke(IMethodInvocation invocation) {
Console.WriteLine("Before: invocation=[{0}]", invocation);
object rval = invocation.Proceed();
Console.WriteLine("Invocation returned");
return rval;
}
}
© Siemens AG, Michael Stal4141
C
O R
P O
R A
T E
T
E C
H N
O L
O G
Y
Software &Engineering Architecture
Advices cont‘d
• Before advice only called before actual method invocation:
• Example counts number of calls
• Method Before() is only method within IMethodBeforeAdvice
public class CountingBeforeAdvice : IMethodBeforeAdvice {
private int count;
public void Before(MethodInfo method, object[] args, object
target) {
++count;
}
public int Count {
get { return count; }
}
}
© Siemens AG, Michael Stal4242
C
O R
P O
R A
T E
T
E C
H N
O L
O G
Y
Software &Engineering Architecture
Advices cont‘d
• After Returning Advice fires after method invocation
• Example counts number of calls
• Method AfterReturning() is only method within IAfterReturningAdvice
public class CountingAfterReturningAdvice : IAfterReturningAdvice {
private int count;
public void AfterReturning(object returnValue, MethodBase m,
object[] args, object target) {
++count;
}
public int Count {
get { return count; }
}
}
© Siemens AG, Michael Stal4343
C
O R
P O
R A
T E
T
E C
H N
O L
O G
Y
Software &Engineering Architecture
Advices cont‘d
• After Throws Advice handles exceptions
• Method must have the following form:
• Note: IThrowsAdvice is just an empty marker interface
• Same implementation class may contain several AfterThrowing methods
public class RemoteThrowsAdvice : IThrowsAdvice {
public void AfterThrowing(RemotingException ex) {
// Do something with remoting exception
}
}
AfterThrowing([MethodInfo method, Object[] args, Object target], Exception subclass)
© Siemens AG, Michael Stal4444
C
O R
P O
R A
T E
T
E C
H N
O L
O G
Y
Software &Engineering Architecture
Introductions
• Introductions used to add interfaces to existing objects
• Interface to be added:
• Implementation class:
public interface IAuditable {
DateTime LastModifiedDate {
get;
set;
}
}
public class AuditableMixin : IAuditable {private DateTime date;public AuditableMixin() {
date = new DateTime();}public DateTime LastModifiedDate {
get { return date; }set { date = value; }
}}
© Siemens AG, Michael Stal4545
C
O R
P O
R A
T E
T
E C
H N
O L
O G
Y
Software &Engineering Architecture
Introductions cont‘d
• Now, we can implement an advisor:
• Which applies the mixin on all objects. We might have constrained the set of objects
public class AuditableAdvisor : DefaultIntroductionAdvisor{
public AuditableAdvisor() : base(new AuditableMixin()){}
}
© Siemens AG, Michael Stal4646
C
O R
P O
R A
T E
T
E C
H N
O L
O G
Y
Software &Engineering Architecture
Using ProxyFactoryObject
• ProxyFactoryObject • Basic way to create AOP Proxy• Required if you need control over ordering and application of pointcuts
and advices• Implements IFactoryObject
• Benefit of using such a factory: advices and pointcuts can be managed by container
© Siemens AG, Michael Stal4747
C
O R
P O
R A
T E
T
E C
H N
O L
O G
Y
Software &Engineering Architecture
Example for ProxyFactoryObject
• Proxy is returned that implements IPerson:
<object id="personTarget" type="MyCompany.MyApp.Person, MyCompany"><property name="name" value="Tony"/><property name="age" value="51"/>
</object><object id="myCustomInterceptor" type="MyCompany.MyApp.MyCustomInterceptor, MyCompany">
<property name="customProperty" value="configuration string"/></object><object id="debugInterceptor" type="Spring.Aop.Advice.DebugAdvice, Spring.Aop"></object><object id="person" type="Spring.Aop.Framework.ProxyFactoryObject, Spring.Aop">
<property name="proxyInterfaces" value="MyCompany.MyApp.IPerson"/>
<property name="target" ref="personTarget"/><property name="interceptorNames">
<list><value>debugInterceptor</value><value>myCustomInterceptor</value>
</list></property>
</object>
Interfaces exported
Advised object
Applied advices
© Siemens AG, Michael Stal4848
C
O R
P O
R A
T E
T
E C
H N
O L
O G
Y
Software &Engineering Architecture
Advanced Topics: Spring.Services
• Spring.Services used with .NET Remoting, Enterprise Services, Web services
• Allows to export PONOs (Plain Old .NET Objects) as COM+ objects, Web services, Remoting Objects
• Allows to use dependency injection for these entities
• Allows to use AOP for these entities
• Example .NET Remoting:
© Siemens AG, Michael Stal4949
C
O R
P O
R A
T E
T
E C
H N
O L
O G
Y
Software &Engineering Architecture
Advanced Topics: Spring.Web
• Spring.Web provides dependency injection to Web pages and user and standard controls
• It also supports bidirectional data binding between controls on a form and a model
• Bidirectional means that data can be stored from controls to model on postbacks, and controls can be initialized from models
• It supports localization
• Spring.Web also externalizes flow control instead of using Response.Redirect and Server.Transfer
© Siemens AG, Michael Stal5050
C
O R
P O
R A
T E
T
E C
H N
O L
O G
Y
Software &Engineering Architecture
Advanced Topics: Spring.Data and Spring.ORM
• Spring supports Transaction Management
• DAO pattern for using NHibernate, iBatis.NET, ADO.NET
• Should arrive soon. No support in version I was able to test
© Siemens AG, Michael Stal5151
C
O R
P O
R A
T E
T
E C
H N
O L
O G
Y
Software &Engineering Architecture
Further Ingredients of Spring.NET
• Threading and Concurrency Support following Doug Lea: ISync, SyncHolder, Latch, Semaphore
• Object Pooling Support
© Siemens AG, Michael Stal5252
C
O R
P O
R A
T E
T
E C
H N
O L
O G
Y
Software &Engineering Architecture
Installation 101
• Installation is simple:• First obtain new version of Spring.NET from
http://www.springframework.net/ (I’ve used v1.1 Preview 2)• Install .msi file
• After installation you‘ll find a new entry in programs list
• Read the online reference document at http://www.springframework.net/doc/reference/html/index.html (or the locally installed documents)
• Spring.NET assemblies available in <YourDrive>:\Program Files\Spring.NET\Spring.NET 1.1 Preview 2\bin\net\1.1\{debug|release}\*.dll
• Additional support libraries in corresponding lib paths
© Siemens AG, Michael Stal5353
C
O R
P O
R A
T E
T
E C
H N
O L
O G
Y
Software &Engineering Architecture
Roadmap (taken from a presentation by Mark Pollack,
• Spring 1.1 PR3 Release
• Framework for WinForms/SmartClient applications 1.2
• Integration withEnterprise Library (Security, Cryptography, etc..)
• ATLAS Integration
• TIBCO Messaging (RV/EMS)
• . . . Your requests and contributions . . .
• Spring.Net.Integration module in CVS• “Script” to kick start full project
© Siemens AG, Michael Stal5454
C
O R
P O
R A
T E
T
E C
H N
O L
O G
Y
Software &Engineering Architecture
Summary
• Spring now available for .NET developers. No more reason to be jealous of Java colleagues
• Spring.NET represents an important enhancement to .NET: DI enables your apps
• It is not just a naive port of Spring for Java
• But, of course, it is subject to continuous evolution
• It takes a time to get used to it but then it makes you more productive
• My recommendation: try it!
© Siemens AG, Michael Stal5555
C
O R
P O
R A
T E
T
E C
H N
O L
O G
Y
Software &Engineering Architecture
Resources
• Documents and installation• http://www.springframework.net/
• Books• No special book on Spring.NET around, but I recommend to read the
Java literature• Professional Java Development with the Spring Framework by Rod Johnson,
Juergen Hoeller, Alef Arendsen, Thomas Risberg, Colin Sampaleanu, Wrox Press, 2005
• Pro Spring by Rob Harrop, Jan Machacek, Apress, 2005
• Articles• http://msdn.microsoft.com/msdnmag/issues/05/09/DesignPatterns/
© Siemens AG, Michael Stal5656
C
O R
P O
R A
T E
T
E C
H N
O L
O G
Y
Software &Engineering Architecture
Q&A