MICROSOFT .NET INTEROPERABILITY FOR BEGINNERS Vjekoslav Babic (Fortempo) ABOUT ME Vjekoslav Babić consultant, trainer, blogger, author Twitter: Mibuso: Blog: @vjekob Vjeko vjeko.com Author of many How Do I… videos for MSDN and PartnerSource for NAV 2013 and NAV 2013 R2 Co-author of “Implementing Microsoft Dynamics NAV 2009” book HOW OTHER PEOPLE SEE PROGRAMMERS HOW PROGRAMMERS SEE OTHER PEOPLE WHAT DO PROGRAMMERS REALLY DO? Most of the time? SO, WHAT DO PROGRAMMERS DO MOST OF THE TIME? % OF TOTAL TIME SPENT PROGRAMMING % OF TOTAL TIME SPENT PROGRAMMING IN C/AL 37.5% OF ALL STATISTICS ARE JUST MADE UP ON THE SPOT WHAT ARE WE DOING HERE TODAY? Basic Concepts • Constructors • Methods • Overloading • Events • Enumerations Slightly Advanced Concepts • Classes and Interfaces • Arrays and Collections • Enumerators • Generics • Reflection • Creating Assemblies • Creating Control Add-ins HOW ARE WE DOING IT? General concepts Managing strings and text Managing dates, times, and numbers Accessing operating system, file system, and the environment Managing data, arrays, collections, and streams Custom assemblies Client Add-ins PART ONE General concepts ASSEMBLIES Building blocks of the .NET Framework Assemblies can be: • Executable files (EXE) • Dynamic Link Libraries (DLL) Assemblies can be deployed to: • Single application: any folder accessible to a .NET application • All applications: Global Assembly Cache (GAC) TYPE .NET Framework is strongly-typed, very similar to C/AL Types can be: • Simple • Complex .NET is object-oriented: • Types can be inherited Two types of complex types: • Classes • Interfaces CLASSES AND INTERFACES Both represent complex types (types that contain members) Classes: • Define the structure • Encapsulate functionality • One class can inherit from only one parent class Interfaces: • Only define the structure, but not the functionality • Represent behaviors of classes • One class can implement multiple interfaces • By convention, names start with I, and many names end with …able THE DotNet DATA TYPE Variables of type DotNet give access to .NET Framework Each DotNet variable specifies: • Assembly • Type DotNet gives access to: • Methods • Properties • Constructors • Enumerations IMPORTANT: CASE SENSITIVITY All .NET Framework identifiers are CASE SENSITIVE PART TWO Managing strings and text System.String A powerful class to handle text information. Maps fully and directly to Text data type in C/AL. METHODS Equivalent to functions in C/AL Methods are defined by their signature. Signature consists of: • Name • Type and kind of parameters (by value, by reference, or output) Return value can be: • Of specific type • void System.String POINTS OF INTEREST Analyzing content • StartsWith • EndsWith • Contains • IndexOf • IndexOfAny • IsNullOrWhiteSpace • LastIndexOf • LastIndexOfAny • Substring Modifying content • Insert • PadLeft • PadRight • Remove • Replace • Trim • TrimStart • TrimEnd System.Text.StringBuilder A very powerful class to handle large text data efficiently. CONSTRUCTORS Create an instance of a class. There is no equivalent in C/AL to constructors. CREATE function for instantiating automation objects is the closest Typically used to: • Initialize the default state of an object • Execute default initialization logic • Limit instantiation SYNTAX OF A CONSTRUCTOR The name of the constructor always matches the class name. This probably looks confusing in C/AL: StringBuilder := StringBuilder.StringBuilder; (why in the Earth do we need all those StringBuilders?) Replace the StringBuilder variable name with s, and it’s more manageable: s := s.StringBuilder; The syntax of the constructor in C/AL is the following: Variable := Variable.[Class Name]({argument1, …}); System.Diagnostics.Stopwatch A simple and useful class to handle time measurements. NAMESPACE A higher-level scope used to organize code Namespace has a many-to-many relationship to assemblies: • One assembly can contain multiple namespaces • The same namespace can span multiple assemblies System.Text.RegularExpressions A namespace containing classes for managing regular expressions. In case you didn’t know: • Regular Expressions (RegEx) are a language used for searching text data through pattern matching • Regular Expressions are SQL of textual data OVERLOADING Capability that allows multiple members to use the same name as long as the signature remains different. C/AL understands overloading of: • Methods • Constructors .NET supports, but C/AL does not understand overloading of: • Indexers • Operators PART THREE Managing dates, times, and numbers System.DateTime Manages date and time information. Maps fully and directly to DateTime data type in C/AL. Many useful properties and methods. PROPERTIES AND FIELDS Properties and Fields are members of complex classes that contain a value. Property: • Always accessible from C/AL • Can be gettable, settable, or both Field: • Never accessible from C/AL System.Globalization Namespace that defines a lot of useful type for managing date and time formats, regional settings, cultures, etc. Useful classes: • Calendar • CultureInfo • DateTimeFormatInfo • NumberFormatInfo System.Globalization.Calendar Manages time division into years, months, weeks, days, etc. System.Globalization.CultureInfo Provides access to culture information. Cultures are the heart of the .NET localization/globalization functionality. System.Globalization.DateTimeFormatInfo Provides access to date and time formatting information. System.Globalization.NumberFormatInfo Provides access to number formatting information. System.Math Provides methods for trigonometric, logarithmic, and other common mathematical functions. System.Numerics.BigInteger Represents an arbitrarily large integer value, without any theoretical upper or lower bounds. System.Convert Converts a base data type to another base data type. PART FOUR Accessing operating system, file system, and the environment System.IO Namespace that provides many useful input and output classes. System.IO.File Provides static methods for the creation, copying, deletion, moving, and opening of files. STATIC OBJECTS AND METHODS Static classes cannot be instantiated Static methods can be called on classes Static classes and members are shared for the whole application domain Microsoft Dynamics NAV Server runs as a single application domain System.IO.Directory Exposes static methods for creating, moving, and enumerating through directories and subdirectories. System.IO.Path Performs operations on String instances that contain file or directory path information. System.IO.FileSystemWatcher Listens to the file system change notifications and raises events when a directory, or file in a directory, changes. EVENTS Enable a class to notify other classes when something of interest happens. Equivalent to C/AL triggers. Events are not automatically exposed. You must first set the WithEvents property. Events can run be: • Server-Side: default behavior, if RunOnClient is No • Client-Side: if RunOnClient is Yes EVENTS ARE NOT AS INNOCENT AS THEY APPEAR Whenever using events, consider: • Client-Side events can only run in pages • Events can be synchronous and asynchronous • Event triggers are only created when the WithEvents is first set to Yes ENUMERATIONS Types that consist of set of named constants. Similar, but not nearly equal to C/AL options. C/AL .NET Always of Integer type Of any integer numeric type, except char Always 0-based 0-based by default, but can be any value Each consecutive element is increased by 1 Every element can have an explicit numeric value, even negative SUPPORT FOR ENUMERATIONS IN C/SIDE NAV 2009 R2 NAV 2013 Does not recognize them Recognizes them You must use integers You can use named values You cannot use bitwise operators (AND, OR, NOT, XOR). You can use + in place of OR, but that’s about it. System.Enum Enables managing enumerations at runtime. MANAGING TYPE INFORMATION AT RUNTIME System.Type GETDOTNETTYPE CANLOADTYPE System.Diagnostics.EventLog Provides interaction with Windows event logs. PART FIVE Handling data • Arrays • Collections • Streams ARRAYS AND COLLECTIONS Arrays: • Contain a fixed number of values of the same data type • Roughly correspond to C/AL arrays (variables with Dimensions property) Collections: • Contain an arbitrary, flexible number of values of the same data type • No equivalent in C/AL Both arrays and collections are extensively used in .NET System.Array Provides methods for creating, manipulating, searching, and sorting arrays. Serves as the base class for all arrays in the common language runtime. ENUMERATORS Enable iterating through arrays and collections. C# uses the foreach keyword to manage the iteration. Two interfaces are in charge of the enumerator-based iteration: • IEnumerable<T> • IEnumerator<T> IEnumerable<T> • Exposes the enumerator IEnumerator<T> • Allows iteration through enumerable object • Current • MoveNext System.Collections.SortedList Represents a list of key/value pairs that are sorted. System.Collections.HashTable Represents a list of key/value pairs that are stored by using a hash table. System.Collections.Generic.List<T> Represents a strongly typed list of objects that can be accessed by index. Provides methods to search, sort, and manipulate lists. GENERICS Allow a single design-time declaration that compiles to multiple run-time types. List<T> can compile to List<int>, List<string>, or List<MyDesiredClass> Supported on: • Classes and interfaces • Methods • Properties • Structures • Fields In C/AL, all generics are of type System.Object System.Collections.Generic.Dictionary<TKey,TValue> Represents a strongly typed collection of keys and values. Provides fast methods to look up content. System.TimeSpan Contains a lot of functionality for managing timespans down to a resolution of 100 nanoseconds. MAPPING .NET TYPES TO C/AL Some types map fully: • String • DateTime • InStream and OutStream Many data types map uni-directionally: • Most simple data types (Boolean, Decimal, Integer, etc.) • Some complex data types (Duration) You cannot use uni-directionally mapped .NET data types in C/AL directly. REFLECTION Capability of .NET to gain insight into itself. Enables managing objects and calling their functionality at runtime without knowing much about the type at design time: • Discovering information about types • Loading assemblies • Instantiating objects • Executing methods • Getting and setting properties • And many more System.IO.Stream A class that provides a generic view of a sequence of bytes. Typical descendants: • System.IO.MemoryStream • System.IO.FileStream Fully mutually interchangeable with both InStream and OutStream C/AL types. Limitation: • CREATEOUTSTREAM and CREATEINSTREAM cannot be called on System.IO.Stream System.Net.WebClient Provides common methods for sending data to and receiving data from a resource identified by a URI. PART SIX Developing Custom Assemblies USING VISUAL STUDIO Creating an assembly Quick overview of C# project structure Adding classes DEPLOYING ASSEMBLIES Client deployment Service Tier deployment Global Assembly Cache (GAC) CLIENT DEPLOYMENT Required for development and Must be deployed in: • 2009: <Program Files (x86)>\Microsoft Dynamics NAV\6.0\Classic • 2013 <Program Files (x86)>\Microsoft Dynamics NAV\6.0\RoleTailored Client <Program Files (x86)>\Microsoft Dynamics NAV\7.x\RoleTailored Client Best practice: • Deploy in separate Add-ins subfolder Assembly is loaded on first design access to the C/SIDE object which uses it Client must be restarted to refresh the loaded assembly SERVICE TIER DEPLOYMENT Per instance of NST Must be deployed in: <Program Files>\Microsoft Dynamics NAV\x.y\<Service> Best practice: • Deploy in separate Add-ins subfolder Deployed assembly is loaded on first call NST must be restarted to refresh the assembly GLOBAL ASSEMBLY CACHE (GAC) Central repository of known .NET assemblies Machine-wide Once registered in GAC, assembly is accessible from anywhere in .NET Allows side-by-side execution of different code versions Requirements: Versioning Strong naming with a public key Deployment to GAC GLOBAL ASSEMBLY CACHE AND C/SIDE C/SIDE is aware of the GAC Objects deployed to GAC are not required to be deployed to Add-ins SIMPLIFYING DEPLOYMENT Always strongly sign assemblies Use Post Build events Always deploy to GAC PART SEVEN Developing Client Add-ins DEVELOPING ADD-IN CONTROLS Creating add-in controls Deploying add-in controls Consuming add-in controls