Transcript Slide 1

Introduction to Spring.NET

Speaker’s Qualifications

Mark Pollack is a founding partner at CodeStreet LLC, a software and consulting firm in the financial services industry.

.NET and J2EE architect and developer specializing in financial front office solutions, EAI, and message based middleware Spring Developer (2003) • JmsTemplate, Annotation abstraction Contributing author • Java Development with the Spring Framework – JMS Section Founder and Co-lead of Spring.NET (2004) Speaker at various Spring related conferences

Outline

Why a .NET version?

Introduction to IoC/AOP Core Spring.NET Technologies • • IoC Container AOP Additional functionality packaged in Spring.Core

Services • Remoting, WebServices, EnterpriseServices Middle Tier Data Access Web Data Access Additional Modules • NHibernate, TIBCO, Threading.Concurrent

Why Spring.NET?

There is always a need for a good application framework, regardless of the platform Makes life easier to companies and developers using both platforms We got spoiled by Spring and wanted to be able to build .NET apps in a similar way The programming model, ideas and architectural concepts in Spring are not platform specific • • Are GoF design patterns platform specific?

“It is as much a collection of best practices as it is a framework.”

Spring.NET Project Overview

Not a blind port of Spring • • .NET developers feel ‘right at home’ Spring.Java developers feel ‘right at home’ Version 1.0 released September 2005 1.0.3/1.1 RC1 October 2006 (Web + Services)

Spring.NET Project Overview

Documentation • ~200 pages reference • API documentation – VS.NET integration “Quick Start” examples with documentation Unit tests with high % code coverage • Continuous Integration ~2,600 downloads/month • More from nightly builds MSI Installer User Forums JIRA issue Tracking Fisheye Repository Browser

Spring’s “Nature”

Layered Framework • • • Control flow driven by core container Can be a one stop shop or just use certain subsystems Separation between the modules is ‘enforced’.

Can also be considered a library • Implementation classes are considered as a public API • ContextRegistry, ProxyFactory, Template classes Not an all-or-nothing solution

Spring.NET Modules

Main Platform

Web AOP Services Desktop Data Access Core

Separate Module Projects

Windows Services NHibernate TIBCO

Spring in relation to the J2EE/.NET stack

Spring is broad but not deep • • Address end-to-end requirements rather than one tier Consistent programming model across different technologies within the stack • Expands on base APIs/technologies that are deep.

Analogy with an ice flow

Spring in relation to the J2EE/.NET stack

J2EE/.NET stack is deep. How much code to implement the following • • • • Distributed Transaction Manager Messaging Server Web Server etc… Analogy with an iceberg • See a small narrow view of a big foundation; the public APIs, above the waterline

Approaches to application configuration

Flow of control in a “traditional” application as it relates to obtaining other objects and services • ‘Your’ code calls out to class libraries and creates other objects and services as necessary.

• • You ‘new’ and configure the objects.

If using interfaces typically create many specialized factory classes.

• Factory classes may or may not configure returned object.

Inversion of Control presents an alternative approach

Scenario

Simplified “PortfolioManager” • Calculate value of portfolio – Obtain collection of instruments by Account ID – Compute the present value of each instrument

public class PortfolioManager { public void CalculatePresentValue(string accountId) { Portfolio portfolio = GetPortfolioFromTradingSystems (accountId); } foreach (Position position in portfolio.Positions) { double baseValue = } PriceInstrument (position.Instrument); position.PositionValue = position.QuantityHeld * baseValue; portfolio.PresentValue += position.PositionValue; } /// other methods . . .

“Traditional” Implementation

Use of interfaces

private Portfolio GetPortfolioFromTradingSystems( string accountId) { ITradingService s = TradingServiceFactory.CreateTradingService(); IList positions = s.GetPositions(accountId); Portfolio p = new Portfolio("Porfolio for account " + accountId); p.Positions.Add(positions); return p; } public double PriceInstrument( Instrument i) { IPricingService p = PricingServiceFactory.CreatePricingService(); return p.PriceInstrument(i); }

PricingServiceFactory Implementation

public class PricingServiceFactory { private static PricingServiceFactory instance = new PricingServiceFactory(); private static IBondPricingService bondPricingService; private static IEquityPricingService equityPricingService; private PricingServiceFactory() { bondPricingService = BondPricingServiceFactory.CreateBondPricingService(); equityPricingService = EquityPricingServiceFactory.CreateEquityPricingService(); } } public static IPricingService CreatePricingService () { DefaultPricingService ps = new DefaultPricingService ps.Initialize

(); return ps; (bondPricingService, }

Summary of Traditional Approach

Meets design goals of interface based design • Issue: Being able to vs. being able to easily. • • Switching implementations is difficult Testing against stub implementation is difficult Code up many factory classes • Pretty soon have dozens of them What about non-trivial configuration • No object is an island – need to resolve collaborating objects • Classic ‘primitive’ data type configuration is often ad-hoc – maxResults, connectionString. Read in and parse .property files, xml etc.

Code noise infrastructure code unrelated to business logic • Tedious, Repetitive, Error Prone – Pushes you in the direction not to do it. – –

Takes discipline

.

Can we do better?

Core Concepts – Inversion of Control

Inversion of Control (IoC) • Framework code is calling ‘your’ application code.

IoC applies to many areas • Messaging - Callback functions – Framework passes ‘Message’ object when available • Configuration management – Framework passes ‘Context’ to obtain references to other objects and services.

– Framework calls your object’s properties directly. Central design principal for other Spring modules • Data Access – Get passed IDbCommand with all resources managed by framework • Similar for other resource intensive APIs

“Pull Style” IoC for Configuration

Dependency Pull • Pull in dependencies and data as required – Object o = context.lookup(“string identifier”); • Looks like JNDI, Directory Service code Contextualized Dependency Lookup • “Context” is pushed into your code by the framework.

– Then pull in dependencies using the context Context is a ‘generic factory’ • No need to write a factory class per object The framework manages dependent object that is pulled in.

• Lifecycle – Create, Configure, Initialize, Destroy, etc… – Typically via framework specific interfaces

“Push Style” IoC for Configuration

Dependency Injection • Object not responsible for looking up resources or dependencies.

• An container creates objects and pushes configuration data/object dependencies into an object by reflection based calls to “standard” object constructor and/or properties Setter Injection • Injection of dependencies via Properties Constructor Injection • Injection of dependencies via constructor arguments Method Injection • Container implements methods at runtime for lookup

Pull Style – Contextualized Dependency Lookup public interface IManagedComponent void PerformLookUp { (Context context); } public class PortfolioManager : ManagedComponent { private ITradingService tradingService; public void PerformLookup(Context context) { tradingService = (ITradingService) context.GetObject

( “bbTradingService” ); } public class BloombergTradingService : IInitialize , IOtherLifecycle { // normal implementation; constructor, properties, etc } public void Initialize () { // allocate resources if necessary etc..

}

Push Style - Dependency Injection

public class PortfolioManager { private ITradingService tradingService; public ITradingService TradingService { get { return tradingService; } set { tradingService = value; } } } public class BloombergTradingService { // normal implementation; constructor, properties, etc } public void Initialize () { // allocate resources etc..

}

Example IoC Configuration

<

object

name="..." type="..."> ... (properties and dependencies)

object

> <

object

name="..." type="..." init-method="Initialize"> ... (properties and dependencies)

object

> ... Other objects

IoC Bootstrapping

Usually get ‘top level’ object via IoC pull • • Done in ‘main’ All dependencies of top level object are ‘wired’

IApplicationContext ctx = ContextRegistry.GetContext(); PortfolioManager mgr = (PortfolioManager) ctx.GetObject (“myPortfolioManager"); Portfolio p = mgr.GetPortfolio(“ACCT123”);

IoC Externalized Configuration

<

object

name ="myPortfolioManager" type ="PricingDemo.PortfolioManager, PricingDemo">

object

> <

object

name="

myTradingService

" type="Bloomberg.TradingService, Bloomberg“>

object

> <

object

name="

myPricingService

" type="PricingDemo.DefaultPricingService, PricingDemo">

object

>

IoC Externalized Configurition

<

object

name="myBondPricingService" type="PricingDemo.DefaultPricingService, PricingDemo">

object

> <

object

name=" basicBondPricingAlgorithm " type="Algorithms.BasicBondPricer, Algorithms"/>

object

> <

object

name=" myMarketDataService " type="Reuters.MarketDataService, Reuters“

init-method

=“init”>

object

>

Dependency Injection Advantages

No lock-in to a particular framework APIs for configuration management Application classes are self-documenting • Dependencies are explicit and always up-to-date No ‘code-noise’ • Key piece of application plumbing is kept out of the way.

Promotes coding to interfaces • Strategy Pattern Application classes are easier to test General IoC advantage • Framework is responsible for reading configuration – Can switch where configuration comes from without changing application code – Greater consistency in configuration management.

IoC Summary

DI has gained a large following Spring supports all types of IoC • Dependency Pull • • Contextualized Lookup Dependency Injection Spring’s goal is to provide the most robust and feature rich IoC container • Singleton support, lazy initialization, support for traditional factory classes, … Spring is not the only game in town – is part of a larger movement … • HiveMind, PicoContainer, SEAM, EJB3 • Castle, StructureMap, ObjectBuilder

Core Concepts - AOP

Another way to think about program structure • Apply common behavior across OO hierarchies – “Cross Cutting Concerns” • Introduce new behavior across OO hierarchies – “Mixins” • • How can that behavior be applied and encapsulated?

– – Think “Decorator” on steroids in terms of functionality Minimize code duplication Non invasive to code – gives flexibility across an entire code base

Good Modularity

XML parsing in org.apache.tomcat

• • red shows relevant lines of code nicely fits in one class

Poor Modularity

logging in org.apache.tomcat

• red shows lines of code that handle logging • • not in just one place not even in a small number of places

Cross cutting concerns

Logging • entry/exit/exception to methods Performance Metrics • Logging with timers Observer design pattern Caching Method return values Security Checks Monitoring • • Alerts via email WMI Transaction Management

Core Concepts - AOP

Decorator • • Can stick in code before a method executes, after it executes, and after it throws an exception “Intercept” a method AOP “Advice” Chain • Chained decorators.

AOP framework provides you with the means to • Define what code gets stuck in (Advice) – Before/After Returning/After Throwing • And where it can get stuck in (Pointcut) – Methods, Conditional Flow • Define the order of the chained advice.

Spring AOP

Spring.NET implements AOP by dynamically generating proxy classes at runtime.

Object obtained from a Spring IoC container can be transparently advised based on configuration • • XML, Attributes.

Can also use programmatic API.

Out-of-box logging, pooling, caching, tx aspects AOP Artifacts are also managed by container • • Pointcuts – where to apply behavior – Methods invocation, Exception throwing.

Advice – what behavior to apply (Spring Terminology) “AOP + IoC is a match made in heaven”

Spring AOP Example

public interface ICommand object Execute { (object context); } public class ServiceCommand : ICommand { public object Execute return null; (object context) { Console.Out.WriteLine("Service implementation : [{0}]", context); } } public class ConsoleLoggingAroundAdvice : IMethodInterceptor { } } public object Invoke(IMethodInvocation invocation) Console.Out.WriteLine("Advice executing; calling the advised method..."); object returnValue = invocation.Proceed(); { Console.Out.WriteLine("Advice executed; advised method returned " + returnValue); return returnValue ;

Creating and Executing a AOP Proxy

ProxyFactory factory = new ProxyFactory(new ServiceCommand()); factory.

AddAdvice (new ConsoleLoggingAroundAdvice()); ICommand command = (ICommand) factory.GetProxy(); command.Execute("This is the argument");

Advice executing; calling the advised method...

Service implementation : [This is the argument] Advice executed; advised method returned

AOP Configuration Example

AutoProxy – Help apply AOP advice across objects in the IoC Container •

ObjectNameAutoProxyCreator

– Wildcards on object names •

DefaultAdvisorAutoProxyCreator

– Regular expression match on method name + advice

English* PortugeseSpeaker debugInterceptor

Transaction Aspect

public class TransactionInterceptor : TransactionAspectSupport, IMethodInterceptor public object Invoke(IMethodInvocation invocation) { Type targetType = ( invocation.This != null ) ? invocation.This.GetType() : null; { TransactionInfo txnInfo = CreateTransactionIfNecessary ( invocation.Method, targetType ); object returnValue = null; } } try { returnValue = invocation.Proceed(); } catch ( Exception ex ) { DoCloseTransactionAfterThrowing ( txnInfo, ex ); } finally { DoFinally ( txnInfo ); } DoCommitTransactionAfterReturning ( txnInfo ); return returnValue;

Attribute driven AOP

Attributes are used to define pointcut and provide the aspect configuration information public interface IAccountManager { void DoTransfer(float creditAmount, float debitAmount); } public class AccountManager : IAccountManager { { . . .

[Transaction()]

public void DoTransfer(float creditAmount, float debitAmount) creditDao.CreateCredit(creditAmount); debitDao.DebitAccount(debitAmount); }

AOP Summary

What it is • • Complementary to good OOP design Solves problems that are difficult to solve with OOP • Leads to cleaner, better modularized code that is easier to maintain and extend.

What it is not • • Experimental Answer to all problems

Spring.NET/Java Comparison

bean->object Ioc/AOP: Spring.NET = Spring.Java 1.2 • .NET has custom schema support but different than Spring.Java 2.0

• .NET has web scoped objects (Session/Application) .Java 2.0

Spring.NET has ‘ConfigureObject’ .NET specific • named constructor args • Indexers Spring.Java has more breath • JMX, no WMI equivalent… • • • WebFlow AspectJ’ized Spring.Java AOP JMS – but coming soon to .NET

Expression Evaluation used for Property Name parsing.

Other functionality in Spring.Core

Spring.Expressions

• Powerful expression language for manipulating an object at runtime • Think OGNL for C# Spring.Validation

• Validation based on expression language Spring.Collections

• ISet, thread-safe Set/Dictionary, PriorityQueue Spring.Threading

• LogicalTheadContext, Semaphore, Latch

Spring Expressions

public class Inventor { public string Name; public string Nationality; public string[] Inventions; private DateTime dob; private Place pob; /// constructors omitted public DateTime DOB { get { return dob; } set { dob = value; } } public Place PlaceOfBirth { get { return pob; } } public int GetAge(DateTime on) { return on.Year - dob.Year; } }

Spring Expressions

Inventor tesla = new Inventor("Nikola Tesla", new DateTime(1856, 7, 9), "Serbian"); tesla.PlaceOfBirth.City = "Smiljan"; string evaluatedName = (string) ExpressionEvaluator.

GetValue (tesla, "Name"); string evaluatedCity = (string) ExpressionEvaluator.

GetValue (tesla, "PlaceOfBirth.City")); ExpressionEvaluator.

SetValue (tesla, "PlaceOfBirth.City", "Novi Sad");

Spring Expressions

Literals •

ExpressionEvaluator.GetValue(null, "6.0221415E+23");

Properties, Arrays, Lists, Dictionaries, Indexers •

"Members[0].Inventions[6]")

Methods • "

Members[0].GetAge(date('2005-01-01')"

Logical, Relational, Math Operations •

"DateTime.Today <= date('1974-08-24')"

Variables

IDictionary vars = new Hashtable(); vars["newName"] = "Mike Tesla"; ExpressionEvaluator.GetValue(tesla, "Name = #newName", vars);

If-then-else Spring Object References

"@MyMovieLister.MoviesDirectedBy('Roberto Benigni').Length

Spring.Services Features

Exports plain .NET objects (PONOs) as • • • Serviced Component, Remote object Web service Exporters to connect .NET client to • • RMI or EJB Uses IIOP.NET library Exported objects can be configured via

Dependency Injection

.

Apply aspects

Spring.AOP

to exported objects using Isolates you from the changes in distributed technology

.NET Remoting Example

“Technology agnostic” calculator

Export as a Singleton SAO

Spring Web

Extends ASP.NET Enables

Dependency Injection

pages and controls for ASP.NET web Enables bi-directional data binding Greatly improves support for data validation Adds localization support Implements ‘result mapping’-based page flow Adds Master Pages support to ASP.NET 1.1

Dependency Injection for ASP.NET

Uses custom IHttpHandlerFactory implementation to perform DI

value="transfer:SuggestedFlights.aspx" />

Spring Data Access

Provide uniform best practice approach across data access technologies.

IoC integration • Connection String management • Resource management – ‘Template’/callback APIs Transaction management • Programmatic and declarative Exception Translation Added value • Make ‘native’ APIs easier to use • Higher level encapsulation of Data Access – DAO support classes, “AdoOperation” objects

Spring.NET Data Access

Spring.Java” users should feel right at home • • ADO.NET, to first order Java ported O/R Mappers, to second order.

ADO.NET framework NHibernate support • iBatis.NET under development.

Early Adopter stage • Well hedged by “Spring.Java” design

Motivations for ADO.NET framework

Provide usable provider independent API • No factory in BCL (.NET 1.1) • Simplistic and at times incomplete interfaces Easier parameter management Exception Handling • Not singly rooted (.NET 1.1) • • Base exception + error code (.NET 2.0) No portable “DAO” exception hierarchy Centralize Resource Management • Using is a great addition! No catch though.

Transaction management • Ad-hoc passing around of Transaction object • Still need to coordinate connections with TxScope

AdoTemplate

Execute()

• • • ICommandCallback, CommandDelegate Use of delegates – i.e. stateless callbacks.

Use of variable length arguments, boxing

ExecuteScalar(), ExecuteNonQuery(), Query()

• IRowCallback, IRowMapper, IResultSetExtractor Variations with • IDbCommandSetter, IDbCommandCreator • One “inline” parameter – string name, Enum dbType, int size, object parameterValue Factory Method for creating

IDbParameters

Standard ADO.NET

public class NativeAdoTestObjectDao : ITestObjectDao { // Connection String Property ...

public void Create(string name, int age) { using (SqlConnection connection = new SqlConnection(connectionString)) { string sql = String.Format("insert into TestObjects(Age, Name) " + "VALUES ({0}, '{1}')", age, name); } } } using (SqlCommand cmd = new SqlCommand(sql, connection) { connection.Open(); comm.ExecuteNonQuery(); }

AdoTemplate Example

public class TestObjectDao : AdoDaoSupport , ITestObjectDao { public void Create(string name, int age) { } } AdoTemplate.ExecuteNonQuery

( String.Format(CommandType.Text, "insert into TestObjects(Age, Name) " + "VALUES ({0}, '{1}')", age, name));

AdoOperations

OO model for DB operations • Preferred approach

AdoQuery

- Result set mapping to objects

AdoNonQuery-

Insert/Update/Delete

AdoScalar –

Return single value

StoredProcedure

• out parameters and multiple result sets

AdoDataSetQuery*

– Return DataSet Use of

ICommandCreater

implementation for efficient parameter re-creation.

Stored Procedure

ADO.NET supports discovery of Stored Procedure parameters.

public class CallCreateTestObject : StoredProcedure { public CallCreateTestObject(IDbProvider dbProvider) Compile(); : base(dbProvider, "CreateTestObject") { DeriveParameters(); } } public void Create(string name, int age) { ExecuteNonQuery(name, age); }

Microsoft Transaction Management

ADO.NET (1.1) EnterpiseServices (1.1) System.Transactions (2.0)

.NET 3.0

Local     Distributed Declarative     Programmatic         The sweet spot • Declarative transaction management + local transactions

Spring.NET PlatformTransactionManager

Abstraction for transaction management • Support for three Microsoft tx technologies

AdoPlatformTransactionManager

• Local transactions

ServiceDomainPlatformTransactionManager

• Distributed transactions

TxScopePlatformTransactionManager

• Local or Distributed as needed.

Switching is just a small configuration change.

Callback interfaces •

ITransactionCallback

O/R Mapping Support

Easy ‘porting’ code/concepts from .NET versions of Java O/R • • NHibernate iBatis.NET

Two levels of support • IoC helpers for central object injection/configuration • Template classes for resource/tx management.

NHibernate Example

public class NativeNHTestObjectDao : ITestObjectDao { // SessionFactory property ...

public void Create(TestObject to) { ISession session = null; ITransaction transaction = null; try { session = SessionFactory.OpenSession(); transaction = session.BeginTransaction(); session.Save(to); transaction.Commit(); } catch { if(transaction != null) transaction.Rollback(); throw; } finally { if(session != null) session.Close(); } } }

NHiberateTemplate DAO Implementation

public class NHTestObjectDao : HibernateDaoSupport , ITestObjectDao { [Transaction()] public void Create(TestObject to) { HibernateTemplate.Save(to); } }

Support for declarative and programmatic transaction management for any data access technology

Spring.NET Messaging

Starting development of TIBCO RV and JMS (ActiveMQ/TIBCO) support • JmsTemplate – send and sync receive • MessageListenerContainer – asynchronous consumption • MessageConverter – Message to Object mapping • MessageListenerAdapter – Combine MessageConverter and listener to call JMS agnostic methods, ala RCP.

JMS based .NET/Java interop

Reflection based Object to Message Converter • • Part of MessageForge OS project Java/C# implementations Objects are converted via reflection to map messages • • Vendor support for nested map messages required Preserves ability to consume from other language bindings.

Java objects automatically translated to .NET via Microsoft’s Java Language Conversion Assistant

Summary

Spring.NET is a robust IoC/AOP solution Similar platform and programming model across .NET/Java Active development Training and Support through Interface21 Suggestions and feedback always welcome.

Upcoming Spring Conference

The Spring Experience 2006 December 7th – 10th, Hollywood Florida Register at

http://www.thespringexperience.com

3 full days, 55 sessions across 5 tracks

Q&A