Presentation is loading. Please wait.

Presentation is loading. Please wait.

Copyright 2004-2007, Interface21. Copying, publishing, or distributing without expressed written permission is prohibited. Introduction to Spring.NET Mark.

Similar presentations


Presentation on theme: "Copyright 2004-2007, Interface21. Copying, publishing, or distributing without expressed written permission is prohibited. Introduction to Spring.NET Mark."— Presentation transcript:

1 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 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 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 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 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 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 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 8 Sample Application Architecture Data Repository Domainobjects DAO implementations Service implementations Web interface Otherinterfaces PresentationLayer ServiceLayer Data Access Layer DAO interfaces Service interfaces

9 9 Spring’s Role Spring- managed Domainobjects DAO implementations Service implementations Web interface Otherinterfaces DAO interfaces Service interfaces Data Repository

10 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 11 Traditional approach (1) public class SimpleBankService : IBankService { private IAccountDao accountDao; public SimpleBankService() { accountDao = new AccountDao(); } // business methods follow … }

12 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 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 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 15 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 16 Constructor Injection public class SimpleBankService : IBankService { private IAccountDao accountDao; public SimpleBankService(IAccountDao accountDao) { this.accountDao = accountDao; } // business methods follow … }...

17 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”>...

18 18 Spring.NET Container in action Spring.NET Lightweight Container Configuration Instructions (Metadata) Your Application Classes Fully configured system Ready for Use produces

19 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 20 Configuration <section name="context" type="Spring.Context.Support.ContextHandler, Spring.Core"/> IApplicationContext context = ContextRegistry.GetContext(); IBankService bankService = (IBankService) context.GetObject("bankService");

21 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 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 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 24 Dependency Injection for ASP.NET Enables DI for –Pages, Controls –Custom HTTP Modules –Standard ASP.NET Providers <add name="Spring" type="Spring.Context.Support.WebSupportModule, Spring.Web"/> <add verb="*" path="*.aspx" type="Spring.Web.Support.PageHandlerFactory, Spring.Web"/>

25 25 Example <property name="Authenticator" ref="authenticationService"/> DI features work with standard ASP.NET page and controls

26 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 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 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 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 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 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 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 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 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 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; } 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 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; } 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 37 AdoTemplate in a Nutshell int userCount = (int) adoTemplate.ExecuteScalar( CommandType.Text, "SELECT COUNT(0) FROM USER"); 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 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 (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 39 AdoTemplate: Lightweight Mapping public class AccountDao : AdoDaoSupport { private string cmdText = "select AccountID, ContactName from Account"; public virtual IList GetAccounts() { return AdoTemplate.QueryWithRowMapperDelegate (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 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 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 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 LocalDistributedDeclarative ADO.NET  EnterpriseServices  System.Transactions *  WCF** *.NET Transaction Management

43 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 44 PlatformTransactionManager creation <db:provider id="DbProvider" provider="SqlServer-2.0" connectionString=“DataSource=${dataSource} …"/> <object id="adoTransactionManager" type="Spring.Data.Core.AdoPlatformTransactionManager, Spring.Data"> Or programmatically…

45 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“>

46 46 Declarative Transactions using XML <object id="bankService” type=“MyServices.SimpleBankService, MyAssembly">... <tx:method name="Get*" timeout="1000" isolation="RepeatableRead" no-rollback-for="SillyException"/> <aop:advisor pointcut-ref="serviceOperation” advice-ref="txAdvice"/> What to do… Where to do it… Tie them together

47 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 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 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 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 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 52 Retry Advice Configuration Leverage SpEL –Specify formula for retry interval –Specify exception to act upon <property name="retryExpression" value="on exception name ArithmeticException retry 3x delay 1s"/> <property name="retryExpression" value="on exception name ArithmeticException retry 3x delay 1s"/> on exception name ArithmeticException retry 3x rate (1*#n + 0.5) on exception name ArithmeticException retry 3x rate (1*#n + 0.5) on exception (#e is T(System.ArithmeticException)) retry 3x delay 1s on exception (#e is T(System.ArithmeticException)) retry 3x delay 1s

53 53 Chaining advice on exception name ArithmeticException wrap MyServices.ServiceOperationException... <aop:advisor pointcut-ref="serviceOperation" advice-ref=“exHandlingAdvice“ order=“1"/> <aop:advisor pointcut-ref="serviceOperation" advice-ref="txAdvice“ order="2"/>

54 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 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 56 Where to get it Download from www.springframework.netwww.springframework.net –Many samples and extensive reference manual Contact: mpollack@interface21.commpollack@interface21.com

57 57 Q&A


Download ppt "Copyright 2004-2007, Interface21. Copying, publishing, or distributing without expressed written permission is prohibited. Introduction to Spring.NET Mark."

Similar presentations


Ads by Google