Share more code on iOS, Android and Windows with Portable Class Libraries
-
Upload
dan-ardelean -
Category
Technology
-
view
92 -
download
0
Transcript of Share more code on iOS, Android and Windows with Portable Class Libraries
SharemorecodeoniOS,Android andWindowswithPortable ClassLibrariesDanArdelean - MahizMicrosoftMVPWindowsPlatformDevelopmentXamarinCertified MobileDeveloperTwitter:@danardeleanEmail:[email protected]
iOS WindowsAndroid
Objective-CXcode
C#VisualStudio
JavaAndroidStudio
Nosharedcode•Manylanguages&developmentenvironments•Multipleteams
SiloApproach
iOS WindowsAndroid
C#VisualStudioXamarinStudio
C#VisualStudio
C#VisualStudioXamarinStudio
C#codebase•100%nativeAPIaccess•Highperformance
Xamarin’s Approach
Xamarin’s Approach
SharedC#codebase•100%nativeAPIaccess•Highperformance
iOSC#UI WindowsC#UIAndroidC#UI
SharedC#Mobile
Xamarin+Xamarin.Forms
TraditionalXamarinApproach WithXamarin.Forms:Morecode-sharing,allnative
iOSC#UI WindowsC#UIAndroidC#UI
SharedC#Backend
SharedUICode
SharedC#Backend
CodeSharingStatsMac
iOS
Android
WindowsPhone
iCircuit TouchDraw
86%
14%
72%
28%
70%30%
61%39%
88%
12%
76%
24%
90%
10%
DataAccessLayer(Database)
• SQLiteincludediniOS+Androidforlocaldatastorage
• canbeaddedtoWindows
• Canalsostoreinthecloud– AzureMobileServices,Amazon,Dropbox,etc.
WebServices
• UseHttpClient forREST services,canthenprocesswith
• System.Xml /System.Json• LINQtoXML• Newtonsoft JSON.net component
• UseWCFor.asmx forSOAP
NuGet
• NuGet isapackagemanagerfor.NETthatallowsyoutolocate,install,updateandremovesharedcomponentsfromyourprojectsrightinyourIDE(eitherVisualStudioorXamarinStudio)
www.nuget.org
XamarinComponent Store
• CanalsogetreusablecomponentsfromtheXamarinComponentStorewhichisaccessiblethroughtheComponentsfolderineachproject
WherecanIusesharedcode?
• Anytimeyouarewritingcodewhichdoesnotdependonaspecificplatformfeature,itispotentiallysharable,particularlyifit:
• Talkstoawebservice• Parsesadataformat• Workswithadatabase• Performsprocessing/businesslogic§• …
• Createsharedclasses+methodsandthenusethemfromyourplatform-specificcodetomaximizetheshareablesurfacearea
SharableCode
• Sharable code is split between reusable components and platform-independent code
40%
60%
Your Code
Components
PlatformSpecificCode
•Whatifwedidn’thavetowritethiscode?
•Whatifwecouldaccessitfromsharedcode?
UI+APIs UI+APIsUI+APIs
BatteryGPSLightsNotificationsSettingsTextToSpeech
BatteryGPSLightsNotificationsSettingsTextToSpeech
BatteryGPSLightsNotificationsSettingsTextToSpeech
SharedProject
AnyNote.Droid.csprojNoteFragment.cs
FreehandFragment.cs
NoteViewController.cs
FreehandViewController.cs
AnyNote.UWP.csproj AnyNote.iOS.csproj
NoteView.xaml.cs
DrawInkView.xaml.cs
PortableClassLibrary
• PortableClassLibrariesareassembliesthatcanbeusedbydifferentflavorsof.NETwithoutrecompiling
Standard- PlatformAbstractions
• Complexrequirementscanbedescribedwithabstractionsthatareimplementedbytheplatformspecificproject
PCLINoteDataLoader
NoteManager
NoteItem
ApplicationUI Layer
NoteDataLoader
ApplicationUI Layer
NoteDataLoader
ApplicationUI Layer
NoteDataLoader
Just need a way for thePCL to know about theimplementation..
Providingconcretedependencies
• CansupplyconcreteimplementationtoPCLviaconstructor,methodorpropertysetter;thistechniqueisoftencalledDependencyInjection
var manager = new NoteManager(new NoteDataLoader());OR
var manager = new NoteManager ();manager.Initialize(new NoteDataLoader ());
ORvar manager = new NoteManager (); manager.Loader = new NoteDataLoader ();
PlatformSpecificCodeStrategies
• CanrestrictyourAPIusagetothelowestcommondenominator,oruseanabstractionsuchasaninterfaceoraneventandimplementthatabstractionintheplatform-specificproject(s)
• NeedsomewaytogettotheabstractioninyourPCLcode
Callbacks Factories
Dependency Injection
Event-BaseExtensibility
• PCLscanuseeventsontypestorequestextensibilityfromtheconsumer,particularlyeffectiveifplatform-specificrequirementsaresmall
public class NoteManager{
public event bool ShowAlert(string title,string message);
void OnDeleteNote(NoteItem note) {if (ShowAlert("Warning!", "...")) {...
}}
}PCL
var notes = new NoteManager();
notes.ShowAlert += (title, message) => {new UIAlertView(title, message,
null, "OK").Show();...
};NoteManager.iOS
FactoryPattern
• Dependenciescanbelocatedthroughfactorieswhichareresponsibleforcreatingtheabstractions
Client Factory Serviceuses creates
DefiningtheFactory
publ ic abstract class AlertService{
publ ic s t a t i c Func<AlertService> Create { get; set; }
publ ic abstract string
bool Show(string title, message,
string yesButton,string noButton);
}
DelegateissetbyplatformwhichreturnsimplementationofthedefinedAlertService
SettingupaFactory
• Eachplatformwouldimplementtheabstractionandthensetthefactorypropertytoadelegatethatreturnstheimplementation
class AlertServiceiOS : AlertService{
publ ic bool Show(string t i t l e , s t r ing message,s t r ing yesButton, s t r ing noButton) { . . . }
}
publ ic override bool FinishedLaunching(...) {. . .AlertService.Create = ( ) => new AlertServiceiOS()
}
UsingaFactory
• Thenanycodeintheprojectthatneededthatfeaturewouldgototheknownfactorytocreatetheobjecttobeused
OnReceivedError(string errorMessage)public void{
var alertService a ler tServ ice. Show
= AlertServ i ce.Cre a te( ) ; ( "E r ro r " ,
{ errorMessage} " , "OK", n u l l ) ;$"Got e r ro r :. . .
}
Nowtheclientdoesn'tneedtoknoworcareabouttheimplementation– itgoestothefactorytogetoneandjustusesitfromanywhereinthe app
ServiceLocator
• ServiceLocatorpatternusesacontainerthatmapsabstractions(interfaces)toconcrete,registeredtypes– clientthenuseslocatortofinddependencies
Client Locator
Service A
Service B
uses
locates
locates
ServiceLocatorExampleDefinition
publ ic sealed class ServiceLocator{
publ ic s t a t i c ServiceLocator Instance { get ; se t ; }
void Add(Type contractType, void Add(Type contractType,
object value); Type serviceType) ;
contractType);
public publicpublic public
object Resolve(Type T Resolve<T>();
Uses Singletonpattern toprovide globalaccessibility
}
Providecapabilitytoregisterandlocate types
RegisterDependencies
appl icat ion)
publ ic p a r t i a l class AppDelegate{
. . .publ ic override void FinishedLaunching(UIApplication{
. . .ServiceLocator.Instance.Add<IAlertService,MyAlertService>();
}}
Platform-specificcoderegistersimplementationforthe abstraction
UsetheServiceLocator
public void DialNumber(string number){
var a l e r t = ServiceLocator.Instance.Resolve<IAlertService>();i f ( !a ler t .Show("Dia l Number",
"Are you sure you want to d i a l " + number,"Yes", "No")) { . . . }
}
Clientthenrequeststheabstractionandlocatorreturnstheregistered implementation
ServiceLocatorImplementations
• Easytorollyourown,buttherearemanyusableimplementationsoutthereifyouarealreadyusing3rdpartylibraries
• CommonServiceLocator[commonservicelocator.codeplex.com]• MostMvvm/PatternlibrarieshaveaServiceLocator• Xamarin.Forms DependencyService
DependencyInjection
• Anotheroptionistohavetheplatform-specificcode"inject"thedependencybypassingitasaparameterorsettingaproperty
publ ic class DataAccessLayer{
publ ic DataAccessLayer (IDbResposito r yIAler tService
db, a le r t s ) { . . . }
ILogger Logger { get; set; }publ ic. . .
}
Servicesthisclassdependsonmust besupplied("injected")through constructorparameters,propertiesormethod parameters
UsingDependencyInjection
• Canthenconnecttheclientandrequireddependenciestogethermanuallyinourcode
CreateDataLayer()publ ic DataAccessLayer{
var dataAccessLayer = new DataAccessLayer(new Sql i teReposi tory( ) ,new WinRTAlertService());
/ // /
IDbRepositoryIAler tService
dataAccessLayer.Logger = new AzureLogger(); / / ILogger
return dataAccessLayer}