37
Mark Gu SunGard (Asset Finance) Developing Next-Gen Enterprise Web Application Enterprise

Developing Next-Gen Enterprise Web Application

  • Upload
    mark-gu

  • View
    330

  • Download
    2

Embed Size (px)

DESCRIPTION

Mark Gu, web architect from SunGard (Asset Finance), will be giving a presentation on how they are using ASP.NET MVC and various client-side technologies to develop their next generation Enterprise web application. The presentation will cover topics and promote discussions around pluggable websites, Knockout JS, Roslyn, code generation, and TypeScript just to name a few.

Citation preview

Page 1: Developing Next-Gen Enterprise Web Application

Mark GuSunGard (Asset Finance)

Developing Next-Gen Enterprise Web Application

Enterprise

Page 2: Developing Next-Gen Enterprise Web Application

Background Goals Challenges & Solutions

Agenda

Page 3: Developing Next-Gen Enterprise Web Application

A global leading provider of leasing and financing software system

Provides end-to-end capability eliminating the need for companies to maintain multiple systems

Has been on the market for more than 10 years More than 100 employees across multiple development

centres: New Zealand, India, and UK

Background - Business

Page 4: Developing Next-Gen Enterprise Web Application

Core product .NET (Windows Forms, .NET Remoting) SQL Server & Oracle Crystal Report

Web portal: external facing, enables access to a small part of the core product

ASP.NET MVC, jQuery & Knockout Highly customizable and extensible

Background - Technology

Page 5: Developing Next-Gen Enterprise Web Application

Migrate the entire Windows-based application to Web-based

No loss of functionality Support customization and extension Modern & responsive UI

Goals

Page 6: Developing Next-Gen Enterprise Web Application

Finding a balance between ease of maintenance and per-client customization

Large code base Complex business & UI logic Existing employees’ skillsets Limited resource and challenging timeline

Challenges

Page 7: Developing Next-Gen Enterprise Web Application

Challenge 1Per-client Customization

Page 8: Developing Next-Gen Enterprise Web Application

Web portal is heavily customized for each client: logos, colours, themes resources, labels, messages page structure, workflows, validations authentication and authorizations other custom features

Clients may want to further extend their web portals Customization for the core product is still highly

desirable

Per-client Customization

Page 9: Developing Next-Gen Enterprise Web Application

Implements the Model-View-Controller pattern promotes separation of concerns and code reusability makes code easier to test

Provides an extremely extensible framework and a lot of customization opportunities

controller factory, router handler, route constraint view engine, Razor view build provider value provider factory, model binder, model validation

and metadata provider action filter, action result, …

ASP.NET MVC

Page 10: Developing Next-Gen Enterprise Web Application

Plug-in architecture using MEF One plug-in site for one client, or a client’s business unit Each site is implemented in a standalone assembly

Registration class Controllers, models CSS style-sheets, images, fonts JavaScript view models Razor views Configuration files

Pluggable Website

Page 11: Developing Next-Gen Enterprise Web Application

All pluggable websites are: deployed to a designated folder in the hosting web application loaded and filtered at the start-up time called into at appropriate times to perform initialization or

other business logic metadata about site name, priority, and dependencies routing table and constraints resources for labels, captions, and notification messages overridden controller or repository logic

Pluggable Website

Page 12: Developing Next-Gen Enterprise Web Application

Pluggable Websitepublic interface ISiteRegistration{ string SiteName { get; } void RegisterDependencies(IDependencyManager dependencyManager); void LoadResources(ResourceGateway resourceGateway); void RegisterIgnoreRoutes(RouteCollection routes); void RegisterRoutes(RouteCollection routes);}

[Export(typeof(ISiteRegistration))][ExportMetadata("SiteName", SiteConsts.SITE_NAME)]public class ClientSiteRegistration : ISiteRegistration{ public string SiteName { get { return SiteConsts.SITE_NAME; } } ...}

internal static class SiteCompositionManager{ private static CompositionContainer _compositionContainer;

public static void Initialize() { var catalog = new AggregateCatalog(); catalog.Catalogs.Add(new AssemblyCatalog(Assembly.GetExecutingAssembly()));

var fullPath = HttpContext.Current.Server.MapPath("~/Sites"); if (Directory.Exists(fullPath)) { foreach (DirectoryCatalog dirCatalog in GetDirectoryCatalogsRecursive(fullPath)) { AppDomain.CurrentDomain.AppendPrivatePath(dirCatalog.Path); catalog.Catalogs.Add(dirCatalog); } }

var filteredCatalog = new FilteredCatalog(catalog, ...); _compositionContainer = new CompositionContainer(filteredCatalog); }

public static void Compose(params object[] parts) { if (_compositionContainer != null) _compositionContainer.ComposeParts(parts); } ...

public class MyControllerFactory : DefaultControllerFactory{ [ImportMany(RequiredCreationPolicy = CreationPolicy.Shared)] private IEnumerable<Lazy<ISiteRegistration, ISiteRegistrationMetadata>> _sites;

public MyControllerFactory() { SiteCompositionManager.Compose(this); ...

public class MyRazorViewEngine : RazorViewEngine { ... }

[BuildProviderAppliesTo(BuildProviderAppliesTo.All)]public class MyRazorBuildProvider : RazorBuildProvider { ... }

Page 13: Developing Next-Gen Enterprise Web Application

One pluggable website may depends on another

Pluggable Website

Core

Client A Client B

BU 1 BU 2

Page 14: Developing Next-Gen Enterprise Web Application

Challenge 2Complex Business & UI Logic

Page 15: Developing Next-Gen Enterprise Web Application

Over 10 years of investment in the current code base More than 3.5 million LOC More than 1000 forms and user controls Complex business logic results in complex UI logic

multi-level cascading dropdowns defaulting rules cyclic fields change notifications dynamic validations in memory states, temporary objects licensing, security role checking (nearly 1000 roles)

Complex Business & UI Logic

Page 16: Developing Next-Gen Enterprise Web Application

Some “UI” logic should have been business logic Some UI logic can be re-expressed as business logic Some UI logic can be expressed using metadata

visible enabled caption lookup validation: required, range, length, etc.

Where should UI logic go?

Page 17: Developing Next-Gen Enterprise Web Application

.NET attributes attached to properties to declaratively express UI logic

Metadata

[ReadOnly(true)]public string A { get; set; }

[Visible(Property="A", Is="Foo")]public int B { get; set; }

[OnChange(Send="Currency,Amount", Refresh="Rate,CalculationDate")]public string D { get; set; }

[Enabled(Property="B", IsGreaterThan=1)]public string C { get; set; }

Page 18: Developing Next-Gen Enterprise Web Application

On page load, metadata is sent to client browser to be processed:

walk the object graph of a view model subscribe to change notifications of the targeted properties on a property’s value change, subscription is triggered and

predefined event handlers are fired Once the plumbing is done in the framework code,

developers don’t have to write a single line of JavaScript

Metadata

Page 19: Developing Next-Gen Enterprise Web Application

Challenge 3Problems Introduced by Metadata

Page 20: Developing Next-Gen Enterprise Web Application

.NET attributes aren’t expressive enough only suitable for extremely simple conditions difficult to read and understand

Lots of magic strings difficult to refactor and results in run-time error

Same logic needs to be repeated for multiple properties Slows page load & increase memory usage (IE8)

Problems Introduced by Metadata

[Visible(Property="Amount" IsGreaterThan=100 And=true Property2="Code" Property2StartsWith="ISO-")]public int A { get; set; }

Page 21: Developing Next-Gen Enterprise Web Application

Attributes now only specifies the name of a method that provides the actual logic

The actual logic can now be written in plain C# statements

Use Roslyn & code generation to parse method bodies and generate equivalent JavaScript statements

Roslyn & Code Generation

[Visible("IsBVisible")]public int B { get; set; }

[Enabled("IsCEnabled")]public string C { get; set; }

Page 22: Developing Next-Gen Enterprise Web Application

Roslyn & Code Generation[Enabled(“IsDepartmentTypeEnabled")]public DepartmentType DepartmentType { get; set; }

public bool IsDepartmentTypeEnabled(){ return WarehouseState == WarehouseState.SelfWH && !string.IsNullOrEmpty(DepartmentName);}

data.DepartmentType.extend({ enable: () => { return data.WarehouseState() === Models.WarehouseState.SelfWH && data.DepartmentName(); }});

ko.extenders.enable = (function (target, evaluator) { target.enable = ko.computed(evaluator); return target;});

ko.bindingHandlers['meta'] = { init: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) { var value = valueAccessor(); if (!ko.isObservable(value)) { return; }

if (_.has(value, 'enabled')) { ko.applyBindingsToNode($(element).find('.form-control')[0], { enable: value['enable'] }, bindingContext); } }};

Page 23: Developing Next-Gen Enterprise Web Application

For each server side model, a dependency manager JavaScript is generated

Can generate .NET proxy classes using the same analysis for QA test scripts

The generation is re-runnable and can be integrated into MSBuild to ensure consistency

Roslyn & Code Generation

public Proxy<int> B { get; set; }

public Proxy<string> C { get; set; }

Page 24: Developing Next-Gen Enterprise Web Application

.NET attributes aren’t expressive enough logics now reside in C# methods, although they still need to be

relatively simple, they can be much expressive Lots of magic strings

remaining magic strings are purely method names, which can be easily validated using Roslyn or ReSharper SDK

Same logic needs to be repeated for multiple properties multiple metadata can now point to the same method

Slows page load & increase memory usage (IE8) subscriptions and event handlers are generated at the compile

time, no runtime parsing and wiring up needed

Roslyn & Code Generation

Page 25: Developing Next-Gen Enterprise Web Application

Challenge 4Existing Employees’ Skillsets

Page 26: Developing Next-Gen Enterprise Web Application

Most developers: are C# developers are used to Windows desktop application development are unfamiliar with JavaScript and CSS have limited Web development experience

Most of business analysts: are used to designing for desktop applications are uncomfortable with Web design paradigm are new to Responsive design & mobile first design concepts

Existing Employees’ Skillsets

Page 27: Developing Next-Gen Enterprise Web Application

Steep learning curve Web hosting: IIS Server technologies: ASP.NET, ASP.NET MVC, SignalR UI technologies: HTML, CSS, cross-browser compatibility CSS framework: Twitter Bootstrap 3rd party UI controls: jQuery UI, Kendo UI Programming language: JavaScript 3rd party JS libs: jQuery, Knockout, Durandal, Require JS, Q, etc. Concepts: async & stateless operations, responsive design Conventions

Existing Employees’ Skillsets

Page 28: Developing Next-Gen Enterprise Web Application

Only a small number of experienced web developers write raw HTML

The rest of developers write in C# Only a small number of experienced UI designers edit

CSS No developers touch CSS A rich set of UI framework elements and templates are

developed to facilitate the above

Say “NO” to HTML & CSS

Page 29: Developing Next-Gen Enterprise Web Application

Similar to Html.EditFor(m => m.Name) A large number of HTML helpers and templates are

developed to ensure: the correct usage of HTML 5 elements consistent CSS classes and styling consistent structure for composite controls the ease of refactoring when design changes all visible texts are properly resourced

HTML Helpers & Templates

Page 30: Developing Next-Gen Enterprise Web Application

HTML Helpers & Templates@using (Html.BeginPanelWithId<FieldSet>(“ContractActions")){ using (Html.BeginPanel<FieldSetLegend>()) { Html.RenderText("Actions"); }

using (Html.BeginPanel<ListPanel>("foreach: allActions")) { using (Html.BeginPanel<ListItem>("template: { name: templateName }")) { } }}

@using (Html.BeginPanel<Panel>()){ Html.Grid<Person>("AllEmployees", "dataSource: employees") .AddColumn(x => x.Id).Grid .AddColumn(x => x.FirstName).Grid .AddColumn(x => x.LastName).Grid .AddColumn(x => x.Age).Grid .AddColumn(x => x.DateOfBirth).Grid .AddColumn(x => x.IsSingle).Grid .AddColumn(x => x.BasicSalary).Grid .Render();}

Page 31: Developing Next-Gen Enterprise Web Application

Enforcement is done by keeping track of created UI elements

can be turned off for “RELEASE” HTML helpers are also designed to be open and flexible

to support power users to handle occasional one-off cases

HTML Helpers & Templates

Page 32: Developing Next-Gen Enterprise Web Application

A rich set of metadata are developed to allow developers to express JavaScript logic using C# constructs

What happens if you really, really have to write in JavaScript?

don’t!!! You write in TypeScript

Say “NO” to JavaScript

Page 33: Developing Next-Gen Enterprise Web Application

A language for application-scale JavaScript development A typed superset of JavaScript that compiles to plain

JavaScript Any browser, any host, any OS Open Source

TypeScript

Page 34: Developing Next-Gen Enterprise Web Application

High level constructs: module, interface, class, enum

Accessibility: public, private, protected

Inheritance: implements, extends, super, overrides

Types: boolean, number, string, null, any, {}

Anonymous type support: { id: number; name: string }

Generic support: Array<string>, Promise<T>

Casting: id: number = <number>obj.Id;

Function overloading and optional parameters: (extraData?: any)

Variable amounts of arguments: format(pattern: string, …args: any[])

Lambda expression: (str1: string, str2: string) => str1 + str2

CommonJS and AMD support: import, export, require

TypeScript – Language Features

Page 35: Developing Next-Gen Enterprise Web Application

Part of Visual Studio 2013 Update 2 Syntax highlighting Brace matching Go to declaration IntelliSense Auto-complete Quick info Compile time type and syntax

checking Generate .js, .min.js, and .js.map files

TypeScript – Visual Studio IDE Features

Page 36: Developing Next-Gen Enterprise Web Application

Type definitions can be created for existing 3rd party JavaScript libraries

Provides type checking and IntelliSense DefinitelyTyped contains more than 440 high quality

type definitions for well-known JavaScript libraries: jQuery, Knockout, Underscore, Node, etc.

The list is growing and updates are frequent

TypeScript – for 3rd Party JS Libraries

Page 37: Developing Next-Gen Enterprise Web Application