Snabbare/enklare utveckling med Webfoundation (RAD) • Förslag som med framgång redan har smygits in i en del kund projekt, testats och givit snabbare utveckling.

Slides:



Advertisements
Liknande presentationer
Snabbguide och tips.
Advertisements

En presentation av ett unikt system
BAS-M Hur du på ett enkelt sätt administrerar din båtklubbs register.
Skapa ett video-CV på YouTube
Formulär Tänkte nu gå igenom vad ett formulär är och hur man kan skapa dem i Access.
Interface.  Interface är en datatyp och har alltså egen syntax och en hel del egna regler för vad arv från interface innebär.  Interface är renodlad.
Grunder i PowerPoint 2000 Skapa en ny presentation Rita egna objekt
API skillnader EPiServer 7 - CMS6R2 Uppgradering från CMS6R2
Relationsdatabasdesign
Hur går det till att rapportera in betyg idag?
void hittaMax(int tal[], int antal, int *pmax) { int i; ??=tal[0]; for(i=1;i??) ??=tal[i]; } int main() { int v[]={1,2,3,4,2}; int.
Access med Sebastian och Robert
Klasser och objekt.
”Ett sätt att distribuera Business Objects via webben”
Algoritmer och data strukturer -Länkade listor
Funktionen SA10-Grupper. Följande typer av grupper finns: - Grupp i kurs hör alltid ihop med en kurskod - Grupp i program hör alltid ihop med en programkod.
Fortsättningskurs i Programmering lektion 6
Logikprogrammering Ons, 25/9
OOP Objekt-orienterad programmering
Tentamensdags och lab 3…. Större program delas normalt upp i flera filer/moduler vilket har flera fördelar:  Programmets logiska struktur när man klumpar.
Metoder i java Det finns två typer av metoder i java
Arv.
Inkapsling.
Polymorfism.
Programmeringsteknik för K och Media
Föreläsning 6 Referenser Objekt som parametrar public/private Klassvariabler och klassmetoder.
Alice in Action with Java
Sid period2CD5250 OOP med C++ Mats Medin MDH/IDT Objektbaserad programmering –Grundläggande om klasser och objekt – (Arv får vänta)  Iden med klasser.
Sid period2CD5250 OOP med C++ Mats Medin MDH/IDT Konstruktor Ser till att objektets data är korrekt initierade MinKlass::MinKlass(); MinKlass::MinKlass(int.
Föreläsning 13 Polymorfism, Paket och JAR-filer. Polymorfism Ordet härstammar från grekiskan Poly – många Morf – form Polymorf – många former Någonting.
Programmering i C# 3. Klasser.
PROCESSPROGRAMMERING
Föreläsning 4 Kö Implementerad med array Implementerad med länkad lista Djup kontra bredd Bredden först mha kö.
Jonny Karlsson PROCESSPROGRAMMERING Föreläsning 4 ( )‏ Innehåll:Trådsäkerhet - Intrinsic locks och synkronisering - Synchronized statements.
Sid 41 Fordon int antalhjul; int vikt;
Föreläsning 2 Kort Översikt Över Javaspråket. Källkodsformat Unicode används åäöμψζ tillåtna Inte alla miljöer klarar av det Källkod Bytekod Java VM för.
4. Arv och dynamisk bindning
ASP.NET MVC4 + NoSQL = Major Awesomness. IoC Container.
Vektorer (klassen Vector) Sortering
Max start-guide Liten och väldigt snabbt ihopkastad.
Mer om arv - Polymorfism Kursbok: “Objects First with Java - A Practical Introduction using BlueJ”, David J. Barnes & Michael Kölling Fredric Ragnar
UTVECKLING MED RAMVERKET.NET Marcus Medina. Dagens visdomsord ” Ingen vet vad han klarar innan han har försökt. ” - Publilius Syrus (85 f.Kr.-43 f.Kr.).
Arv.
Programmeringsteknik för Media1 & K1
Mitt första Java program Mahmud Al Hakim Copyright, Mahmud Al Hakim, 1.
Föreläsning 8 Arv och abstrakta klasser. Arv Definierar en klass utifrån en redan existerande klass Den nya klassen utökar den ärvda klassen ( extends.
Jonny Karlsson INTRODUKTION TILL PROGRAMMERING Föreläsning 8 ( ) INNEHÅLL:Klasser: -Konstruktorer -Klassvariabler -Instansmetoder -Privata.
Riktade listor i C och Java Lösning till gruppövning 1.
1 Föreläsning 6 Programmeringsteknik och Matlab 2D1312/2D1305 Metoder & parametrar Array API och klassen ArrayList.
WIPCORE PRESENTATIONSMALL  TEXT: Förutom de element som redan är stylade (t.ex. versala rubriker) finns det ett par andra riktlinjer. –Ord du vill markera.
Föreläsning 1 Reserverade ord Javas API Identifierare Litteraler Variabler Kompilering och interpretering.
UTBILDNING FÖR SIBA I WEB FOUNDATION Erik Brandin, 16 februari 2010.
Föreläsning 9 Gränssnitt. Super Super kan användas till anrop av en omdefinierad metod Super kan användas till anrop av konstruktorer i superklassen Super.
F4 - Funktioner & parametrar 1 Programmeringsteknik, 4p vt-00 Modularisering ”svarta lådor” Väl definierade arbetsuppgifter Enklare validering Enklare.
KONSTEN ATT SKRIVA BRA ÅTERANVÄNDBAR KOD Pierre Setteskog, Pontus Munck
Jonny Karlsson PROCESSPROGRAMMERING Föreläsning 8 ( )‏ Innehåll:  Introduktion till Java EE (Enterprise Edition)  Enterprise Java Beans.
Föreläsning 4 Klasser Och Objekt.
Föreläsning 17 Repetition. Källkodsformat Unicode används åäöμψζ tillåtna i namn på identifierare Inte alla miljöer klarar av det Källkod Bytekod Java.
1 Ingenjörsmetodik IT & ME 2007 Föreläsare Dr. Gunnar Malm.
OOP F5:1 Stefan Möller OOP Objekt-orienterad programmering Föreläsning 5 Klasser och objekt Skapa objekt - new Referenser Konstruktorer Inkapsling.
Programmeringsteknik
Programmeringsteknik för K och Media
William Sandqvist Funktionsbibliotek När man utvecklat en funktion så långt att den är "färdigutvecklad" kan man lika gärna spara den på.
OOP - teori1 OOP del II– Föreläsning 5 vecka 6. OOP - teori2 Klasser Substantiv i singularis stavat med stor bokstav till exempel Human Dog Account Circle.
1 Föreläsning 2 Reserverade ord Javas API Identifierare Litteraler Variabler Kompilering och interpretering.
1 Föreläsning 6 Repetition på metoder Referenser Objekt som parametrar public/private Klassvariabler och klassmetoder.
OOP&M - teori1 OOP del II– Föreläsning 2 vecka 46 Konstruktorer Instansmetoder Kapitel 14 i kursboken.
Karlstads universitet Datavetenskap DAVA07/08 JE,MG,MG,PS Kontraktsprogrammering.
OOP&M - teori1 OOPM del II– Föreläsning vecka Mer om ärvning.. Abstrakta klasser/metoder Gränssnitt/Interface klasser.
BEANS NÖJD KUND INDEX 2015 Resultat från webbenkät.
Presentationens avskrift:

Snabbare/enklare utveckling med Webfoundation (RAD) • Förslag som med framgång redan har smygits in i en del kund projekt, testats och givit snabbare utveckling. – Konfigurerbar model(Mapper) med alternativt factory lager. – Mapper som alternativt Factory lager – Kontrollerbaserad MVC – Autoregistrering i Autofac – Använda standard MVC i största utsträckning eller open source alternativ, t.ex. form validation,js,css minifiering etc. • En fördel med dessa tekniker är att man kan smyga in dessa tekniker i nyutveckling på befintliga WF projekt.

Konfigurerbar produkt modell Vad • Konfigurerbart kunna välja vilken data man vill ha ut i vyn för produkter. • T.ex. kan utvecklare eller kund (med viss risk  ) konfigurerbart välja vilken data som behövs i vyn för en produkt sida eller produktlistning eller relaterade produkter, carten etc. • Borde utökas för att klara alla Enova objekt som adress mm.

Konfigurerbar produkt modell Fördelar • Snabbare/enklare utveckling (slipper överlagra faktories, modeller och vill du t.ex. läsa av pris finns det troligen redan en klass för detta) • Går att anpassa model strukturen mer då det är mer otypat (lugn i en vy kan man enkelt ändra). • Bättre prestanda då allt automatiskt cachas och cachningen går att konfigurerbart kund anpassa. (T.ex. kan man välja att inte cacha pris men produkt namn beroende på språk. Vidare så riskerar man inte att läsa av properties som inte behövs för specifik kund. • Enklare att återanvända då kund specifika properties separeras ut i en egen klass. • Möjliggör att en specifik sida som t.ex. en produktlistning kan innehålla olika properties beroende på produkt. (Förutom att konfigurera önskade properties kan man programmatiskt välja properties) • Oberoende av CMS.

ImageMapper ProductlistController RenderAction Hjälp jag behöver html’en för produktlistningen CmsProductlistController Vy och model för CMS’en ProductlistService Aktuella Enova produkter ProductlistMapper Model för produktlistningen (Factory) ProductConfigMapper Hjälp ge mig modellen för varje produkt i produktlistningen med de properties som är konfigurerade Otypad (Dictionary) Model (ProductConfigViewModel) för varje produkt ProductConfigurationService UrlMapper PriceMapper EnovaPropertyMapper Dessa properties skall läsas av och de skall läsas av t.ex. på bara produkten och/eller varianter etc. CMS Produktlistningssida Produkt x1, pris,lager Produkt x2, pris,lager Produkt x3, pris,lager Produkt x4, pris,lager Produkt x5, pris,lager Produkt x6, pris,lager Produkt x7, pris,lager Produkt kategori x LookupVaryByProductService Dessa produkter skall du läsa av properties på Property värdet För tillfället konfigureras allt i en xml fil (runtime settings). Men alternativa servicar som läser från Backoffice kommer/kan enkelt skapas. Man kan enkelt lägga till egna kund anpassade property mappers. EnovaPropertyMapper kan läsa vilken property som hellst som finns på enova objektet medan t.ex. PriceMapper bara kan läsa av price. Konfigurerbar produkt modell flödet för t.ex. en produktlistning.

Konfigurerbar produkt modell Property mapper • INamedPropertyMapper används för mappers som klarar av en specifik property som t.ex. pris. • IPropertyMapper klarar av properties beroende på produkt eller konfigurering. T.ex. Enova properties, bild urler till olika storlekar som konfigureras med ett namn. • Allting anropas med: _productConfigMapper.Map(WebFoundationProduct, pageId)

Konfigurerbar produkt modell Property mapper • Ett exempel på hur man gör en property mapper som returnerar true eller false om produkten finns i lager. (Notera att kravet att det skall vara en lista av strängar troligen kommer att ändras.) • public class IsInStockMapper : INamedPropertyMapper • { • private readonly IWarehouseService _warehouseService; • private readonly IsInStockMapperSettings _settings; • public IsInStockMapper(IWarehouseService warehouseService,IsInStockMapperSettings settings ) • { • _warehouseService = warehouseService; • _settings = settings; • } • public string PropertyName • { • get { return "Stock"; } • } • public List Map(WebFoundationProduct product,string pageId) • { • //TODO borde in i WarehouseServicen • double stockQuantity = 0; • if (product.IsVariantOwner) • { • stockQuantity = product.GetVariantMembers ().Sum(p=>_warehouseService.GetStockQuantity(p)); • } • else • { • stockQuantity = _warehouseService.GetStockQuantity(product); • } • return new List { (stockQuantity > _settings.InStockTreshold).ToString(CultureInfo.InvariantCulture) }; • } • public string DefaultVaryBy • { • get { return null; } • }

Konfigurerbar produkt modell xml konfiguration • För tillfället stöds bara xml konfiguration men backoffice stöd är önskvärt också. • I runtimme_settings.xml ställer man in följande exempel: • Location anger man i koden t.ex. produktsida, produktlistning, relaterade produkter dvs plats i siten. PageIdentifier är valfrit, är man på en sida som inte är konfigurerad går den på inställningar för t.ex. Location.Properties • Man kan ställa in att i produktlistningen skall t.e.x. Name läsas av även på dess varianter med: • För tillfället finns följande alternativ som man kan utöka genom arv eller interface (LookupVaryByProductService ): public HashSet GetVaryByProductList(WebFoundationProduct product, string varyBy) { switch (varyBy) { case "Product": return new HashSet () { product }; case "ProductOrVariants": if (product.IsVariantOwner) return new HashSet (m_productService.GetVariants(product)); return new HashSet () { product }; case "VariantDefault": return new HashSet () { m_variantService.GetDefaultVariant(product) ?? product }; case "Variants": return new HashSet ( m_productService.GetVariants(product) ); case "ProductAndVariants": var productList= new HashSet (m_productService.GetVariants(product)); productList.Add(product); return productList; default: return null; }

Konfigurerbar produkt modell Lathund • Fråga: Jag vill läsa av en property som det inte finns stöd för idag. Svar: Skapa en property mapper genom att implementera IPropertyMapper eller INamedPropertyMapper • Fråga: jag vill läsa av samma properties på alla varianter eller produkter som ingår i ett paket. Svar: Ärv/implementera (I)LookupVaryByProductService Eller skapa en ny property mapper som slår upp de andra produkterna och läser propertyn på dem också. • Fråga: Jag vill special anpassa cachningen själv. Svar: Implementera IPropertyValuesCacheService eller ärv/implementera (I)ProductConfigMapper. • Fråga: Jag vill inte bara returnera en dictionary med strängar utan en mer komplicerad objekt hiarki som produktens attribut kategoriserad på attributtyp. Svar: Skapa en specifik property mapper för det som inte returnerar en sträng. • Fråga: Jag har redan en typad modell och vill inte behöva skriva om allt. Svar: Det går att kombinera med befintliga kundlösningar genom att du på din befintliga model lägger till en property med typen ProductConfigViewModel och anropar ProductConfigMapper.Map. • Fråga: jag vill läsa av vissa properties på produkten när jag är i produktlistningen och vissa på produkt sidan. Svar: Man kan namnge olika sammanhang kallat location och t.om konfigurera per sida. • Fråga: När är det inte lämpligt att använda detta? Svar: För tillfället stöds inte formulär data med detta då man måste göra en ny modelbinder som förstår den otypade datan. Eller när affärslogik måste läsa av modellen. • Fråga: Kan inte prestandan bli dålig om jag måste slå upp samma Enova objekt flera gånger. Svar: Mellanlagra i httpcontext som t.e.x: public class AttributeValuesMapper : IPropertyMapper { protected EnovaAttributeType GetAttributeType(Context context, string property) { var key = "AttributeValuesAsStringMapper." + property; if (HttpContextFactory.Current.Items.Contains(key)) return HttpContextFactory.Current.Items[key] as EnovaAttributeType; var type = context.FindObject (property); HttpContextFactory.Current.Items[key] = type; return type; }

Mapper (Factory) • Mapper är ett försök till att förenkla Factory lagret i Webfoundation. • Motsvarar ungefär Factory.Create. • Factory namnet kan lätt förväxlas med design patternet medans Mapper begreppet är inarbetat som t.e.x. AutoMapper. Namnet förklarar mer vad det gäller. Skapa och mappa data från Enova till en vy model. • Modell klassen innehåller ingen kod bara properties. Pg.a. detta behöver modell klassen inget interface (Förutom om properties med validations attribut behöver variera med kundlösningar). • Model klassens properties bör alltid vara för formaterade strängar som url, förformaterade priser etc. Detta för att få bort logik i vyn och effektivisera cachning. • Mapper är inte singelton vilket gör att man enklare kan mellan lagra data som är jobbig att hämta i klassen. T.ex.. CartMapper vill kanske spara undan aktuell valuta etc istället för att slå upp det för varje cart rad. • Mappers har bara en Metod: viewModel Mapper.Map(EnovaObject). • Man skapar en mapper per model klass för singel responsible. Så CartMapper kan anropa CartItemMapper. • Stödjer Autofac på ett bättre sätt. • Mappers för anropa services mm. Man bör sträva efter att ha affärslogik i service klasserna och bara presentations logik i mappern. • Man bör försöka hålla sig till max två nivåer av mappers som anropar varrandra. Ett sätt är att platta ut model vyn och inte spegla enova objekt hiarkin rakt av. Eller anropa renderaction om modellen under inte är kopplad till huvud modellen.

Mapper Anrop • Mappers anropar man i sin controller genom att först anropa en service för att hämta grunden till sin enova data och sedan anropar man mapperns Map metod. public class CartController : Controller { private readonly ICartService _cartService; private readonly ICartMapper _mapper; public CartSurfaceController(ICartService cartService, ICartMapper mapper) { _cartService = cartService; _mapper = mapper; } public PartialViewResult MiniCart() { var cart = _cartService.GetCartOrCreateNew(); var model = _mapper.Map(cart); return PartialView(model); }

Mapper CartMapper model public class CartViewModel { public List CartItems { get; set; } public string TotalPriceWithCurrency { get; set; } } public class CartItemViewModel : ICartItemViewModel { public int ProductID { get; set; } public string ProductArtNr { get; set; } public string Name { get; set; } public string Description { get; set; } public string PriceWithCurrency { get; set; } }

Mapper CartMapper public interface ICartMapper { CartViewModel Map(EnovaCart cart); } public class CartMapper : ICartMapper { private readonly Func _createCartModel; private readonly ICartItemMapper _cartItemMapper; public CartMapper(Func createCartModel, ICartItemMapper cartItemMapper) { _createCartModel = createCartModel; _cartItemMapper = cartItemMapper; } public virtual ICartViewModel Map(EnovaCart cart) { var model = _createCartModel(); var context = cart.GetContext(); model.CartItems = cart.GetCartItems ().Select(item => _cartItemMapper.Map(item)).ToList(); model.TotalPriceWithCurrency = context.AmountToString(totalPrice, context.CurrentCurrency, context.CurrentCurrency.Decimals, true, true); return model; }

Mapper CartItemMapper public interface ICartItemMapper { CartItemViewModel Map(CartItem cart); } public class CartItemMapper : ICartItemMapper { private readonly Func _createCartItemModel; private readonly ImageService _imageService; protected bool _showPriceIncludingTax; public CartItemMapper(Func createCartItemModel, ImageService imageService) { _createCartItemModel = createCartItemModel; _imageService = imageService; _showPriceIncludingTax = true; } public virtual ICartItemViewModel Map(CartItem cartItem) { var context = cartItem.GetContext(); // General var model = _createCartItemModel(); model.Name = cartItem.Name; // Product if (cartItem is EnovaProductCartItem) { var productCartItem = cartItem as EnovaProductCartItem; model.ProductArtNr = productCartItem.ProductIdentifier; model.Quantity = productCartItem.Quantity; model.Image = _imageService.GetImage(productCartItem.Product, ImageService.ImageSize.Small); model.PriceWithCurrency = context.AmountToString(productCartItem.Product.Price, context.CurrentCurrency, context.CurrentCurrency.Decimals, true, true); } return model; } }

Mapper (Factory) • Möjligen kanske alla mappers bör vara konfigurerbara mappers. • I exemplet innan med cart och cartitems kan man tänka sig en property mapper som klarar av cartitems och som för varje item anropar ConfigMapper.

MVC kontrollbaserat • I Webfoundation kör man strikt MVC, dvs en model som typat är komplett för en hel sida, vilket har en del nackdelar.

MVC kontrollbaserat • Kör man kontroll baserat dvs där man i vyn anropar RenderAction får man en mycket enklare lösning och mer lös kopplat. • Färre nivåer i modellen och factories som anropar varrandra. • Lättare att lägga till och ta bort saker på sidan. Som t.ex. lägga till en modell för twitter på sidan eller ta bort model för varianters färger. • Alla vyerna och koden för en kontroll kan man enklare samla ihop i ett projekt eller en folder. Vilket enklare gör att man kan återanvända eller anpassa koden. • Enklare att output cacha delar av sidan.

MVC kontrollbaserat • Det betyder inte att man struntar i att separera ui från logik som i web.forms. • I exemplet med produktlistning, kan man t.e.x. lägga följande klasser i samma folder: – ProductListController med en subaction – Modell klasserna. – Eventuella servicar specifikt för denna. – Vyerna måste tyvärr läggas separat under views men kan samlas under foldern ProductList. • På så sätt ser man enklare var gemensamma funktioner ligger och man bör sträva efter att försöka kategorisera ner de under respektive kontroll folder såvida det inte är en generell funktion. Detta kan leda till att det blir enklare att stycka upp stora servicar. • Man bör dock kanske inte gå till absurdum som i web.forms kontroller som pratar med varandra och undvika renderaction i stora for loopar.

MVC kontrollbaserat Exempel sida • Ett exempel på en sida och vilka kontroller den skulle kunna delas in i (hela sidan anropas av en huvud controller med sidans cms data): Nyheter Produktlistning Topmeny Sök Varukorg Reklambanner Produkt tips Login (Betyg)

MVC kontrollbaserat Exempel kod • Exempel på hur det kan se ut i vyn: – • I Controllern (notera hur jag kan få aktuell sida som inparameter då all routing data från sidan automatiskt skickas vidare.) [ChildActionOnly] public PartialViewResult List(int cmsid, string layout) { var pageId = cmsid.ToString();

Autoregistrering med Autofac • Målet är att utvecklaren inte skall behöva bry sig så mycket om Autofac och dess komplexitet. Utvecklaren skapar bara en klass vars namn slutar med t.ex. Service så kan han injekta servicen sen med dess interface. Vill man byta ut en klass i Webfoundation skapar utvecklaren bara en klass som implementerar samma interface elelr ärver av webfoundation klasssen (Allt utan att behöva skriva någon Autofac registering). • Förenklare modularisering av sin kod då man inte har registrering i en jätte modul eller applikations start. • Auto registrerar alla typer i ens projekt genom namn konventioner eller klass attribut. • Ta bort servicelocator klasser från WF och istället köra med strikt konstruktor injection. (Inget med autoregistrering men borde göras)

Autoregistrering med Autofac Exempel kod • Registrera din Autofac modul på standard sätt, fast istället för att fylla den med massa registreringar anropa RegisterAllKnownServicesInAssembly, te.x. public class MyModule : Module { protected override void Load(ContainerBuilder builder) { //will autoregister all types in this assembly with naming convention builder.RegisterAllKnownServicesInAssembly(this.GetType().Assembly); • Som valfria argument kan man skicka in vilka typer som inte skall registreras och vilka namn konventioner som skall gälla. Detta kan man även ställa in i web.config

Autoregistrering med Autofac web.config • Följande web.config inställningar finns: • WebFoundation.AutoRegister.ExceptTypes Gör att ingen autoregistrering kommer att ske på önskade typer (komma separerat fullständigt namn) som standard blank. • WebFoundation.AutoRegister.singletonNameConventionEndsWith Autogeristrera alla klasser som singelton vars klass namn slutar med som standard: "Service", "Repository", "Provider", "Listener","Factory" • WebFoundation.AutoRegister.newInstanceEachTimeNameConventionEndsWith Autogeristrera alla klasser att skapas upp alltid vars klass namn slutar med som standard: "Model", "Mapper", "Filter", "ViewData", "Settings" • WebFoundation.AutoRegister.httpRequestNameConventionEndsWith Autogeristrera alla klasser att skapas upp per http request vars klass namn slutar med som standard: För tillfället inga då det är lite besvärligt att http request måste vara tillgängligt och att den inte nergraderar till ny instans varje gång annars. • WebFoundation.AutoRegister.containerNameConventionEndsWith Autogeristrera alla klasser att skapas upp per scope vars klass namn slutar med som standard: inga. • Standard värdena kan ändras. Fördelen med namn konventioner är att man mer kommer att följa dem och att man får rätt livstid på objekten utan att behöva tänka på det.

Autoregistrering med Autofac Attribut • Om man inte vill använda sig av namn konvention kan man använda sig av följande klass attribut. • ExcludeFromAutoregister Klassen följer en namn konvention men man vill inte registrera den automatiskt. • Alla följande attribut har ett name argument om man vill registrera klassen med ett namn som t.ex. en MVC controller som kan se ut så här: [AutoRegister(Named = "controller.newspage")] public class NewsPageController : FoundationController { • AutoRegisterAsSingelton • AutoRegisterAsNewInstanceEachTime • AutoRegisterAttribute Samma som AutoRegisterAsNewInstanceEachTime • AutoRegisterAsContainer • AutoRegisterAsHttpRequest