Introduction to Spring .NET

basiliskcanoeSoftware and s/w Development

Nov 2, 2013 (3 years and 10 months ago)

113 views

Copyright 2004
-
2007, Interface21. Copying, publishing, or distributing without expressed written permission is prohibited.

Introduction to Spring .NET

Mark Pollack, Interface21

Founder & Co
-
Lead Spring .NET


2

Agenda


The who, what, why of Spring.NET


Feature overview


Dependency Injection


ASP.NET Framework


Data Access and Declarative Transaction
Management


Aspect
-
Oriented programming


Summary

3

Spring for .NET


Spring.NET provide comprehensive infrastructural
support for developing enterprise .NET™
applications


Apache License
-

Commercial
-
friendly


Created, supported and sustained by Interface21


Integrates with other frameworks and solutions


.NET 1.0/1.1/2.0


Spring Framework for Java has shown real
-
world
benefits


Architectural concepts and patterns applicable to .NET


9 out of the world’s 10 largest banks use Spring Java



4

Spring .NET Benefits


Enables the creation of loosely coupled systems


Increase application testability


Apply enterprise services to objects in a
declarative, non
-
invasive way.


Increase developer productivity when using ‘low
level’ APIs




5

Spring’s “Nature”


Inversion of Control (
IoC
) container to perform
Dependency Injection (DI)


Aspect Oriented Programming (AOP)


Portable Service Abstractions


‘Export’ object to specific middleware technology


Support libraries to tame complex APIs for
common scenarios


Transaction Management, ADO.NET, ASP.NET


Spring deals with the plumbing


Address end
-
to
-
end requirements rather than one tier


Can be one stop shop or just use certain sub
-
systems.




6

Spring .NET Assemblies

Core

IoC

Container + base
functionality

AOP

Services

Portable Service
Abstractions

Web

ASP.NET Framework

Data

DAO / TX Mgmt

Web Extensions

AJAX

NHibernate

Testing

NUnit

7

Where to use in your application?


Dependency Injection to wire together


Architectural layers


Interface with implementation


Configure application for a given deployment
environment


AOP adds functionality across well defined
locations in code


Error handing in controllers


Transactional service layer


Support libraries to implement application
logic within each layer


Integration testing



8

Sample Application Architecture

Data Repository

Domain

objects

DAO implementations

Service implementations

Web interface

Other

interfaces

Presentation

Layer

Service

Layer

Data

Access

Layer

DAO interfaces

Service interfaces

9

Spring’s Role

Spring
-

managed

Domain

objects

DAO implementations

Service implementations

Web interface

Other

interfaces

DAO interfaces

Service interfaces

Data Repository

10

The road to Dependency Injection


How do objects find their collaborators and
why does it matter?


Important to build in accommodation for points of
variation


Architectural Layers


Strategy Pattern


Less re
-
engineering over time, increase testability


Traditional approach


Object ‘pulls in’ collaborators


Inversion of Control approach


Framework calls into object to set collaborators


Dependency Injection calls into standard object
signatures







11

Traditional approach (1)

public class
SimpleBankService

:
IBankService


{


private
IAccountDao

accountDao
;



public
SimpleBankService
()


{


accountDao

= new
AccountDao
();


}




// business methods follow …

}


12

Traditional Approach (2)

public class
SimpleBankService

:
IBankService


{


private
IAccountDao

accountDao
;



public
SimpleBankService
()


{


accountDao

=
AcctDaoFactory.Create
();


}





public void Initialize()



{




// read
-
in property values



}


// business methods follow …

}


13

Pain Points with Traditional Approaches


Difficult to accommodate change


Tight coupling


Rolling your own factory leads to busy work, i.e.
need to code a factory per product


Limited testability


Testing imposes accommodating alternate
implementations


Code noise


Poor separation of concerns


Lack of consistency


Can introduce extraneous compile time dependencies


Team members code factory differently

14

Spring’s
IoC

Container


Heart of Spring .NET


Facilitates full stack plain object
-
based
development


Within any environment


ASP.NET, WinForms/WPF, Web Services/WCF,
COM+, Console, Unit Tests.


By providing


A powerful object factory that manages the
instantiation, configuration, decoration, and
assembly
of your business objects



15

Dependency Injection


Dependency Injection


Uses standard .NET properties and/or constructors to
“inject dependencies”


Dependencies are explicit and resolved at runtime


In majority of cases, no container API is required


Works with existing classes


Benefits


Changing implementations is easy


Loosely coupled


Productivity
-

facilitates agile practices (TDD)


Consistency
-

use common approach to configuration

16

Constructor Injection

public class
SimpleBankService

:
IBankService

{


private
IAccountDao

accountDao
;



public
SimpleBankService
(
IAccountDao

accountDao
)


{


this.accountDao

=
accountDao
;


}



// business methods follow …

}


<object id="
bankService
” type=“
SimpleBankService
,
MyAssembly
">


<constructor
-
arg

name=“
accountDao
“ ref=“
accountDao
”/>

</object>


<object id=“
accountDao
” type=“
SimpleAccountDao
,
MyDaoAssembly
">


<property name=“
MaxResults
” value=“100”/>


...

</object>


17

Property Injection

public class
SimpleBankService

:
IBankService


{


private
IAccountDao

accountDao
;



public
IAccountDao

AccountDao



{


get { return
accountDao
; }


set {
accountDao

= value; }


}




// business methods follow …

}


<object id="
bankService
" type=“
SimpleBankService
,
MyAssembly






lazy
-
init=“true”>


<property name=“
AccountDao
” ref=“
accountDao
” />

</object>


<object id=“
accountDao
” type=“
SimpleAccountDao
,
MyDaoAssembly
">


...

</object>



18

Spring .NET Container in action

Spring.NET

Lightweight

Container

Configuration

Instructions

(Metadata)

Your Application
Classes

Fully configured
system

Ready for Use

produces

19

Creating and configuring container


IObjectFactory


Implementations such as XmlObjectFactory


IApplicationContext


Superset of IObjectFactory


Create using ‘new’ or configure via
App.config



IApplicationContext

context =


new
XmlApplicationContext
(
"assembly://MyAssembly/MyProject/objects.xml");


IBankService

bankService

= (
IBankService
)
context.GetObject
(
"
bankService
");


20

Configuration

<
configuration
>



<
configSections
>


<
sectionGroup

name
="spring">


<
section

name
="context"



type
="
Spring.Context.Support.ContextHandler
,
Spring.Core
"/>


</
sectionGroup
>


</
configSections
>



<
spring
>


<
context
>


<
resource

uri
=“assembly://MyAssembly/MyProject/objects.xml"/>


</
context
>


</
spring
>

</
configuration
>



IApplicationContext

context =
ContextRegistry.GetContext
();


IBankService

bankService

= (
IBankService
)
context.GetObject
(
"
bankService
");

21

Spring
IoC

Summary


1
st

order as feature rich as Spring Java


Container implementation similar enough to
allow easy migration of features


Annotation based configuration


Scripted objects (
IronPython
/
IronRuby
)


Will sync some new features in future releases


If nothing else, use DI to push your
application in the direction of following best
practices!


Loose coupling
-
> easier to test
-
> resiliency to
change


22

Agenda


The who, what, why of Spring.NET


Feature overview


Dependency Injection


ASP.NET Framework


Data Access and Declarative Transaction
Management


Aspect
-
Oriented programming


Summary

23

Spring ASP.NET Framework Goals


“Embrace and extend” ASP.NET


Pain points with ASP.NET are addressed


Pages depend on middle
-
tier services, how to obtain?


Data binding is only in one direction and supported only
by some controls


Need to manage data model supporting the page


Lifecycle methods should be at higher level of abstraction


Data validation is tied to the UI and is simplistic


Simplify ASP.NET development as much as
possible by filling in the gaps


24

Dependency Injection for ASP.NET


Enables DI for


Pages, Controls


Custom HTTP Modules


Standard ASP.NET Providers

<
httpModules
>


<
add

name
="Spring"


type
="
Spring.Context.Support.WebSupportModule
,
Spring.Web
"/>

</
httpModules
>


<
httpHandlers
>


<
add

verb
="*"
path
="*.aspx"


type
="
Spring.Web.Support.PageHandlerFactory
,
Spring.Web
"/>

</
httpHandlers
>

25

Example

<
object

type
="Login.aspx">


<
property

name
="Title"
value
="Hello World"/>


<
property

name
="Authenticator"


ref
="
authenticationService
"/>

</
object
>


<
object

type
="CustomControl.ascx">


<
property

name
="Message"
value
=“Hello from Control"/>

</
object
>


DI features work with standard ASP.NET page
and controls

26

Data Model Management:

Without Spring.NET


public partial class
MyPage

: Page

{


private
MyModel

myModel
;



public void
Page_Load
(object sender,
EventArgs

args
)


{


if (
IsPostBack
)


{


myModel

= (
MyModel
) Session[
"
mySavedModel
"];


}


else


{


myModel

= new
MyModel
(…);
// or more often, use DAO to load


}


}



public void
Page_PreRender
(object sender,
EventArgs

args
)


{


Session[
"
mySavedModel
"] =
myModel
;


}

}

27

Data Model Management:

With Spring.NET


public partial class
MyPage

:
Spring.Web.UI.Page

{


private
MyModel

myModel
;



protected override void
InitializeModel
()


{


myModel

= new
MyModel
(…);
// or more often, use DAO to load


}




protected override void
LoadModel
(object
savedModel
)


{


myModel

= (
MyModel
)
savedModel
;


}




protected override object
SaveModel
()


{


return
myModel
;


}

}

28

Copyright 2006 Solutions for Human Capital Inc. and Interface21 Ltd.

Copying, publishing, or distributing without expressed written permission is prohibited.

Handling form submission:

Without Spring.NET


public class
MyPage

: Page

{


public void
ProcessBuyOrder
(object sender,
EventArgs

args
)


{


try


{


string
stockSymbol

=
txtStockSymbol.Text
;


int

numberOfShares

=
int.Parse
(
txtNumberOfShares.Text
);




BuyOrder

order = new
BuyOrder
(
stockSymbol
,
numberOfShares
);


ITradingService

tradingService

=
ServiceLocator.GetService
(...);


OrderConfirmation

confirmation =
tradingService.ProcessOrder
(order);


Context.Items
["confirmation"] = confirmation;


Server.Transfer
("BuyConfirmation.aspx");


}


catch (
ParseException

e)


{


// handle exception (sometimes this is difficult as well)


}


}

}

29

Handling form submission:

With Spring.NET


public class
MyPage

:
Spring.Web.UI.Page

{


private
BuyOrder

order;


private
OrderConfirmation

confirmation;


private
ITradingService

tradingService
;


// properties omitted



protected override
InitializeDataBindings
()


{


BindingManager.AddBinding
(“
txtStockSymbol.Text
”, “
Order.StockSymbol
”);


BindingManager.AddBinding
(“
txtNumberOfShares.Text
”, “
Order.NumberOfShares
”)


.
SetErrorMessage
(“error.number.of.shares.not.int”, “
errNumberOfShares
”);


}



public void
ProcessBuyOrder
(object sender,
EventArgs

args
)


{


if (
ValidationErrors.IsEmpty

&& Validate(order,
orderValidator
))


{


confirmation =
tradingService.ProcessOrder
(order);


SetResult
(“
buyConfirmation
”);


}


}

}


30

Spring ASP.NET Framework Summary


DI enable ASP.NET


Bi
-
directional data binding


Object scopes


application, session, request


Code becomes more business and less
infrastructure focused


Tight integration with Data Validation
Framework

31

System.Web.Mvc


Next generation web framework


MVC Based


url

maps to controller method invocation


Design Goals


Testable

:
IHttpRequest
,
IHttpResponse


Extensible : View engine,
IoC

container


In Java MVC was the norm


Moving to event based web model
-

JSF


Spring for Java is popular MVC framework


Spring.NET Roadmap


Integration in standard extensibility locations…


Validation, bindings, localization, exception handling,
tag
libs
….


32

Agenda


The who, what, why of Spring.NET


Feature overview


Dependency Injection


ASP.NET Framework


Data Access and Declarative Transaction
Management


Aspect
-
Oriented programming


Summary

33

Spring Data Access Goals


Wide range of data access strategies and
technologies to choose from


APIs tend to be complex and verbose


Accounts for much of code in an application


Multiple APIs for transaction management and quirks


Provide simple and consistent approach to
data access across persistence technologies


Remove incidental complexity


Simplify use of ADO.NET


Technology neutral exception hierarchy


Transaction management abstraction


34

Problems with traditional ADO.NET


Results in redundant, error prone code


Hard to write provider independent code


Code is coupled to transaction API


Verbose parameter management


35

Redundant Code

public
IList

FindAllPeople
() {



IList

personList

= new
ArrayList
();


try


{


using (
SqlConnection

connection = new
SqlConnection
(
connectionString
))


{


string
sql

= "select Name, Age from ...";



using (
SqlCommand

command = new
SqlCommand
(
sql
, connection))


{


connection.Open
();


using (
SqlDataReader

reader =
command.ExecuteReader
())


{


while (
reader.Read
())


{


string
name =
reader.IsDBNull
(0) ?
string.Empty

:
reader.GetString
(0
);


int

age =
reader.IsDBNull
(1) ? 0 : reader.GetInt32(1);


Person
person

= new Person(name, age);


personList.Add
(person);



}


}


}


}


}


catch
(Exception e) { //throw application exception }


return
personList
;

}

36

Redundant Code

public
IList

FindAllPeople
() {



IList

personList

= new
ArrayList
();


try


{


using (
SqlConnection

connection = new
SqlConnection
(
connectionString
))


{


string
sql

= "select Name, Age from ...";



using (
SqlCommand

command = new
SqlCommand
(
sql
, connection))


{


connection.Open
();


using (
SqlDataReader

reader =
command.ExecuteReader
())


{


while (
reader.Read
())


{


string name =
reader.IsDBNull
(0) ?
string.Empty

:
reader.GetString
(0);


int

age =
reader.IsDBNull
(1) ? 0 : reader.GetInt32(1);


Person
person

= new Person(name, age);


personList.Add
(person);



}


}


}


}


}


catch (Exception e) { //throw application exception }


return
personList
;

}

The bold matters
-

the
rest is boilerplate

Null values
could be
handled better

37

AdoTemplate in a Nutshell

int

userCount

= (
int
)
adoTemplate.ExecuteScalar
(


CommandType.Text
,


"
SELECT COUNT(0) FROM USER
");


Acquisition of the connection


Creation of the command


Participation in the transaction


Execution of the statement


Processing of the result set


Handling of any exception


Display or rollback on warnings


Dispose of the reader, command


Dispose of the connection

All handled
by the
template

38

DAO implementation
-

AdoTemplate


Encapsulates boiler
-
plate ADO.NET code


Centralizes management of resource and
tx


private string
cmdText

=


"select count(*) from Customers where
PostalCode

= @
PostalCode
";


public virtual
int

FindCountWithPostalCode
(string
postalCode
)

{


return
AdoTemplate.Execute
<
int
>(delegate(
DbCommand

command)


{



command.CommandText

=
cmdText
;


DbParameter

p =
command.CreateParameter
();


p.ParameterName

=
"@
PostalCode
";


p.Value

=
postalCode
;


command.Parameters.Add
(p);




return (
int
)

command.ExecuteScalar
();


});

}

39

AdoTemplate: Lightweight Mapping



public class
AccountDao

:
AdoDaoSupport

{



private string
cmdText

= "select
AccountID
,
ContactName

from Account";




public virtual
IList
<Account>
GetAccounts
()

{




return
AdoTemplate.QueryWithRowMapperDelegate
<Account>(
CommandType.Text
,


cmdText
,





delegate(
IDataReader

dataReader
,
int

rowNum
)
{



Account
account

= new Account();


account.ID =
dataReader.GetString
(0);


account.ContactName

=
dataReader.GetString
(1);


return account;



});


}


}

}

Specify the command

Do the work for each iteration

40

Stored Procedures

public class
CallCreateAccount

:
StoredProcedure

{



public
CallCreateAccount
(
IDbProvider

dbProvider
)


: base(
dbProvider
, "
CreateAccount
") {


DeriveParameters
();


Compile();


}



public void Create(string name,
int

id) {


ExecuteNonQuery
(name, id);


}

}


variable length argument

41

Transaction Management


How to satisfy the requirement


“The service layer must be transactional”


Adding boilerplate code in the service layer
(
programmatic

transaction management)


Is prone to errors; of omission, cut
-
n
-
paste


Ties implementation to transaction implementation


The solution


Declarative

transaction management

42








*

Promotion to distributed transaction for common designs

**

Only for WCF services

However, what we want to do most often is:


Declarative with local transactions

Local

Distributed

Declarative

ADO.NET







EnterpriseServices







System.Transactions


*





WCF
**


*





.NET Transaction Management

43

Spring .NET Transaction Management


Consistent model for different transaction APIs


IPlatformTransactionManager


AdoTransactionManager


ServiceDomainPlatformTransactionManager


TxScopePlatformTransactionManager


HibernateTransactionManager


Declarative transaction demarcation strategies


XML or Attributes


Using a different transaction manager is a
change of configuration, not code

44

PlatformTransactionManager

creation


<
db:provider

id
="
DbProvider
"


provider
="SqlServer
-
2.0"


connectionString
=“
DataSource
=${
dataSource
} …"/>



<
object

id
="
adoTransactionManager
"


type
="
Spring.Data.Core.AdoPlatformTransactionManager
,
Spring.Data
">




<
property

name
="
DbProvider
"
ref
="
DbProvider
"/>


</
object
>




Or programmatically…

45

Declarative Transactions using Attributes

public class
SimpleBankService

:
IBankService

{



[Transaction()]


public Account Create(string name){


Account
account

=
accountDao.Create
(name)


if (
RequiresSecurity
(account)) {


securityDao.CreateCredentials
(account);


}


return account;


}


. . .

}


<object id=“
bankService
"


type=“
MyServices.SimpleBankService
,
MyAssembly
“>


<property name=“
AccountDao
” ref=“
accountDao
” />


<property name=“
SecurityDao
” ref=“
securityDao
” />

</object>


<
tx:attribute
-
driven/>

46

Declarative Transactions using XML

<object id="
bankService



type=“
MyServices.SimpleBankService
,
MyAssembly
">


. . .

</object>


<
tx:advice

id="
txAdvice
">


<
tx:attributes
>


<
tx:method

name="Get*"


timeout
="1000
" isolation="
RepeatableRead
"



no
-
rollback
-
for="
SillyException
"/>


</
tx:attributes
>

</
tx:advice
>


<object id="
serviceOperation
“ type=“
RegularExpressionPointcut
">


<property name="pattern" value=“
MyServices
.*Service.*"/>

</object>


<
aop:config
>


<
aop:advisor

pointcut
-
ref="
serviceOperation



advice
-
ref="
txAdvice
"/>

</
aop:config
>

What to do…

Where to do it…

Tie them together

47

Under the hood


One use of Aspect Oriented Programming


Transaction aspect encapsulates


Start/stop/rolling back of transaction around method
invocation


Application to service layer objects


ADO.NET implementation binds current
connection/
tx

pair to thread local storage

ConnectionTxPair

connectionTxPairToUse

=


ConnectionUtils.GetConnectionTxPair
(
DbProvider
);

48

Agenda


The who, what, why of Spring.NET


Feature overview


Dependency Injection


ASP.NET Framework


Data Access and Declarative Transaction
Management


Aspect
-
Oriented programming


Summary

49

Aspect Oriented Programming


Modularizes general functionality needed in
many places in your application


Examples


Logging


Transaction Management


Caching


Exception Translation


Performance Monitoring


Custom Business Rules


Security

50

Aspect Library


Configure pre
-
built aspects


Example: Exception Translation


Configuration using DSL


Leverage Spring Expression Language for fine level control

on exception name
ArithmeticException


wrap
MyServices.ServiceOperationException

on exception


(

#e is T(
SqlException
) &&


#
e.Errors
[0].Number in { 154, 165, 178 } )


translate


new
DataAccessException
(‘Error in #
method.Name
’, #e)


51

Retry Aspect


Remote calls are unreliable


If remote operation is idempotent, can retry
until achieve success


Can apply advice based on attribute [Idempotent]


Similar approach as exception advice

on exception name
ArithmeticException

retry 3x delay 1s

52

Retry Advice Configuration


Leverage SpEL


Specify formula for retry interval


Specify exception to act upon

<object name="
exceptionHandlingAdvice
" type="
Spring.Aspects.RetryAdvice
,
Spring.Aop
">


<property name="
retryExpression
"


value="
on exception name
ArithmeticException

retry 3x delay 1s
"/>

</object>

on exception name
ArithmeticException






retry 3x rate (1*#n + 0.5)

on exception (#e is T(
System.ArithmeticException
))





retry 3x delay 1s

53

Chaining advice

<object name=“
exHandlingAdvice


type=
"
ExceptionHandlerAdvice
"
>


<property name="
exceptionHandlers
">


<list>


<value>
on exception name
ArithmeticException



wrap
MyServices.ServiceOperationException


</value>


</list>


</property>

</object>


<
tx:advice

id="
txAdvice
“>

. . .
</
tx:advice
>


<object id="
serviceOperation
“> . . .
</object>


<
aop:config
>


<
aop:advisor

pointcut
-
ref="
serviceOperation
"


advice
-
ref=“
exHandlingAdvice
“ order=“1"/>


<
aop:advisor

pointcut
-
ref="
serviceOperation
"


advice
-
ref="
txAdvice
“ order="2"/>

</
aop:config
>

54

Who is using Spring .NET


Mercado Eletrônico: Leading Latin American B2B


See case study in .NET Developers Journal


Siemens


Banking


Oracle Consulting (Israel)


diamond:dogs

Web Consulting (Austria)


Knorr


sportnet


Panorama Tours


ATV


Libro


A global leader in the online travel booking space


55

Summary


Spring .NET lets you view your application as a
set of components


Each component is


Focused on solving your domain problem


Testable in isolation


The container


Manages the ‘glue code” required for component
creation, configuration, and assembly


Decorates your components with additional behavior


Tame complex APIs and solve generic problems

56

Where to get it


Download from
www.springframework.net


Many samples and extensive reference manual



Contact:
mpollack@interface21.com




57

Q&A