1 / 66

Introduction to Spring.NET

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.

tolla
Download Presentation

Introduction to Spring.NET

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Introduction to Spring.NET

  2. 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

  3. 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

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

  5. 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)

  6. 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

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

  8. Desktop Web AOP Services Data Access Core Spring.NET Modules • Main Platform • Separate Module Projects Windows Services NHibernate TIBCO

  9. 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

  10. 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

  11. 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

  12. 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 . . . }

  13. “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); }

  14. 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 (bondPricingService, equityPricingService); ps.Initialize(); return ps; } }

  15. 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?

  16. 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

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

  18. “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

  19. Pull Style – Contextualized Dependency Lookup public interface IManagedComponent { voidPerformLookUp(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.. } }

  20. 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.. } }

  21. Example IoC Configuration <objects> <object name="..." type="..."> ... (properties and dependencies) </object> <object name="..." type="..." init-method="Initialize"> ... (properties and dependencies) </object> ... Other objects </objects>

  22. 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”);

  23. IoC Externalized Configuration <objectname="myPortfolioManager" type="PricingDemo.PortfolioManager, PricingDemo"> <property name="TradingService" ref="myTradingService"/> <property name="PricingService" ref="myPricingService"/> </object> <object name="myTradingService" type="Bloomberg.TradingService, Bloomberg“> <property name="ConnectionString" value="http://nytrade01:5005"/> </object> <object name="myPricingService" type="PricingDemo.DefaultPricingService, PricingDemo"> <property name="BondPricingService" ref="myBondPricingService"/> <property name="EquityPricingService" ref="myEquityPricingService"/> </object>

  24. IoC Externalized Configurition <object name="myBondPricingService" type="PricingDemo.DefaultPricingService, PricingDemo"> <property name="MarketDataService" ref="myMarketDataService"/> <property name="BondPricingAlgorithm" ref="basicBondPricingAlgorithm"/> </object> <object name="basicBondPricingAlgorithm" type="Algorithms.BasicBondPricer, Algorithms"/> <property name="Calendar" value="DEFAULT"/> </object> <object name="myMarketDataService" type="Reuters.MarketDataService, Reuters“ init-method=“init”> <property name="service" value="7500"/> <property name="network" value="lan1"/> <property name="daemon" value=""/> </object>

  25. 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.

  26. 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

  27. 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

  28. Good Modularity • XML parsing in org.apache.tomcat • red shows relevant lines of code • nicely fits in one class

  29. 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

  30. 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

  31. 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.

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

  33. Spring AOP Example public interface ICommand { object Execute(object context); } public class ServiceCommand : ICommand { public object Execute(object context) { Console.Out.WriteLine("Service implementation : [{0}]", context); return null; } } 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; } }

  34. 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

  35. 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 <object id="ProxyCreator" type="Spring.Aop.Framework.AutoProxy.ObjectNameAutoProxyCreator, Spring.Aop"> <property name="ObjectNames"> <list> <value>English*</value> <value>PortugeseSpeaker</value> </list> </property> <property name="InterceptorNames"> <list> <value>debugInterceptor</value> </list> </property> </object>

  36. 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; } }

  37. 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); }

  38. 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

  39. 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.

  40. 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

  41. 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; } }

  42. 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");

  43. 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

  44. 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 to exported objects using Spring.AOP • Isolates you from the changes in distributed technology

  45. .NET Remoting Example • “Technology agnostic” calculator <object id="singletonCalculator" type="Services.AdvancedCalculator, Services"> <constructor-arg type="int" value="217" /> </object> • Export as a Singleton SAO <objects xmlns="http://www.springframework.net" xmlns:r="http://www.springframework.net/remoting"> <r:saoExporter targetName="singletonCalculator" serviceName="RemotedSaoSingletonCalculator" /> </object>

  46. Spring Web • Extends ASP.NET • Enables Dependency Injection for ASP.NET web pages and controls • 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

  47. Dependency Injection for ASP.NET • Uses custom IHttpHandlerFactory implementation to perform DI <object id="masterPage" type="~/Master.aspx" /> <object id="basePage" abstract="true"> <property name="Master" ref="masterPage"/> </object> <object type="TripForm.aspx" parent="basePage"> <property name="BookingAgent" ref="bookingAgent" /> <property name="AirportDao" ref="airportDaoProxy" /> <property name="TripValidator" ref="tripValidator" /> <property name="Results"> <dictionary> <entry key="displaySuggestedFlights" value="transfer:SuggestedFlights.aspx" /> </dictionary> </property> </object>

  48. 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

  49. 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

  50. 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

More Related