MonthSeptember 2016

DataContractSerializer

DataContractSerializer made its first appearance with release of WCF but can operate outside WCF.

DataContractSerializer can serialize types decorated with DataContract, MessageContract, Serializable attributes, types that implement IXmlSerialisable and all public types without Attributes.

During serialization Reference integrity is by default not preserved. You can preserve it by setting “IsReference = true” to DataContract attribute. Note that this approach my cause problems if DataContractSerializer is not serializer who will deserialize data.

 

You can also use OnSerializing, OnSerialized, OnDeserializing, OnDeserialized Attributes to fine-grain your serialization process.

This tutorial will explain how to serialize and deserialize types by decorating type with DataContract attribute.

First we use need to add reference to System.Runtime.Serialization. Secondly we decorate the type with DataContract Attribute, and inside type wee decorate fields and properties with DataMember Attribute. Then we instantiate DataContractSerializer instance and use its WriteObject and ReadObject methods to serialize/deserialize data.

Example of DataContractSerializer:

By using DataMember Attribute we can serialize automatic properties, because property itself will be serialized and not its backing field.

Because DataContractSerializer does not store type and assembly information we need to tell it which is the type we wish to serialize by specifying type in the DataContractSerializer constructor.

As no type or assembly information are preserved be sure to supply KnownType  Attribute to your base class to be able to use inheritance properly.

DataContractSerializer

Data Contract Serializer

 

You can download solution from this link.

To return to other serialization techniques return to this location.

Binary serialization

Today’s topic is Binary serialization, if you wish to read more about serialization or other types of serialization please visit this link:

Binary serialization is type of serialization where type fidelity and reference integrity are preserved, meaning assembly information, private and public fields are being preserved as well as theirs memory locations. You would normally use binary serialization to preserve application state, store it to a backing store (storage medium) and use it later to run application on same computer or maybe multiple other computers.

Hearth of binary serialization is BinaryFormatter class and its Serialize and Deserialize methods. Serialize and Deserialize  methods take two parameters stream and object graph and serialize or deserialize object accordingly. Result of serialization are unreadable to human eye but you can read some information:

Binary Formatter

BinaryFormatter serialization result

As you can see type and field information are preserved.

If you wish serialized data in more readable way you can use SoapFormatter. Note that SoapFormatter is obsolete so use it only for debugging and testing purposes.

SoapFormatter

SoapFormatter serialization result

To mark a type serializable use Serializable attribute to decorate type. Serializable attribute is not inherited so if you wish to serialize both base and derived class decorate both of them with serializable attribute. Other approach would be to implement ISerializable interface.

If you wish not to serialize filed add NonSerialized attribute.

You can serialize null types, but you can not serialize or deserialize null streams.

Properties are not serialized but their private fields are. Do not serialize auto implemented properties because you cannot guarantee that theirs private fields will have the same name on the other machines as they do on yours.

If we wish more control during Serialization/Deserialization processes we can use attributes from System.Runtime.Serialization and apply them to the methods.
Attributes we can use for methods during serialization:
OnSerializingAttribute – use this attribute to prepare data before deserializing . For example encrypt password field or change distance from miles to kilometers.
OnSerializedAttribute – restores type to a status it was before applying OnSerializingAttribute.

Attributes we can use for methods during serialization:
OnDeserializingAttribute – because serialization cannot use constructor, use this attribute for method that will simulate constructor, and maybe set fields to default values.
OnDeserializedAttribute – use this attribute to manually set value of the fields just after serialization process has finished.

 

Example for Binary serialization.

We will try to serialize data from Employee class:

 

 

Download link for entire solution is here.

Serialization and Deserialization

Serialization is the process of transforming an object or object graph
into a stream of bytes or text. Similarly,  deserialization is the process of transforming bytes into an object or object graph.

Object graph: In computer science, in an object-oriented program, groups of objects form a network through their relationships with each other—either through a direct reference to another object or through a chain of intermediate references. These groups of objects are referred to as object graphs.

So, object graph can be a single List of string, entire class or even state of application.

Usage of serialization can wary, weather you want to communicate between two applications on one PC, save state of an Application on your local hard-drive or maybe in cloud… possibilities are endless.

What can I serialize?

You cannot serialize methods or delegates, but you can serialize fields and properties. That is why we can use DTO models (Data transferable models). DTO models are classes with properties that represent data that we want to represent. You have seen some examples so far, like Employee class.

To make this class more readable you could just add DTO suffix after Employee and everybody would know that this is an DTO class.

We will inspect how to serialize and deserialize data by using:

  1. Binary serialization,
  2. Custom serialization,
  3. XML Serializer,
  4. JSON Serializer,
  5. Data Contract Serializer

Among these XML Serializer and JSON Serializer are the most common ones but as we progress between each one of them you will see that other serialization mechanisms have their usage.

 

Preprocessor Directives

Preprocessor directives are instructions that we give to the compiler and compilers job is to compile code based on those instructions.

All preprocessor directives must begin with hash(#) sign, but do not need to end with semicolon(;) because they are not statements.

Preprocessor directives are not inherited and are file specific.

List of preprocessor directives:

#define
#undef
#if
#else
#elif
#endif
#warning
#error
#line
#region
#endregion
#pragma
#pragma warning
#pragma checksum

Continue reading

WinMD Assembly

Windows 8 introduced WinRT(Windows Runtime) that allows us to develop applications based on C++, C#, Vb and JavaScript by allowing access to its Api and by allowing communication between different programming languages. Communication between languages is possible through Windows Runtime Component that creates WinMD Assembly. WinMD Assembly is a Assembly that contains metadata but can also contain types.

When you try to create Windows 8.1 store app you cannot add usual Class Library, you have to add Windows Runtime Component and there you can write your usual code.

Trying to add Class library to your Store App will result in “Unable to add a reference to project” error.

WinMD limitations (copied from https://www.microsoftpressstore.com/articles/article.aspx?p=2199428&seqNum=3):

  • The fields, parameters, and return values of all the public types and members in your component must be WinRT types.
  • Public structures may not have any members other than public fields, and those fields must be value types or strings.
  • Public classes must be sealed. If your programming model requires polymorphism, you can create a public interface and implement that interface on the classes that must be polymorphic. The only exceptions are XAML controls.
  • All public types must have a root namespace that matches the assembly name, and the assembly name must not begin with “Windows.”

Why would I need to create WinMD class library?

Lets explore it through Windows store app example.

Create new Solution and there add two Blank App.s for Windows 8.1 (one for C# and another for JS).

Both of these apps should have:

2x Textbox

1x Label

2x Button

Goal of this Application is to create Application where you can input data inside two different TextBoxes and combine their values inside Label after clicking button. Second goal is to copy some text value in your clipboard(simply copy some text with Ctrl+C) and display value in Label after clicking second button.

All this code can be easily achieved by writing it in backend of MainPage.xaml.cs file or inside JavaScript function, but we want our Application to share code, and that is here WinMD steps in. You can create methods that perform that actions and reuse it across different applications and different languages. Yup, even JavaScript can use WinMD classes written in C#.

Example of WinMD / Windows Runtime Component Assembly

MainPage.xaml

default.html

MainPage.xaml.cs – Buttons

Windows Runtime Component – Helper class

If you wish to inspect entire solution , download it from this link.

Please do not use code from solution  for your projects because no checks were implemented what so ever.

 

GAC (Global Assembly Cache)

You can locate GAC folder inside Windows directory. GAC folder contains only strongly named assemblies. All applications that are running on your machine can access GAC folder and use its assemblies. Benefits of storing strongly named assemblies inside GAC are:

  • There is no need to distribute that particular assembly with every new version of application
  • Assemblies stored in GAC folder are strongly named so you need not to worry about having two or more version of same assembly distributed.

How can i locate GAC folder?

There are actually two locations:

  1. Location for assemblies created with .Net Framework 2.0 to .Net Framework 3.5
  2. Location for assemblies created with .Net Framework 4.0 and newer

Usually you cal locate it by typing C:\Windows\assembly for older strongly named assemblies or C:\Windows\Microsoft.NET\assembly for newer strongly named assemblies.

If your machine is not installed on C drive or your windows folder is not named Windows simply type in File explorer : %WINDIR%\Assembly or %WINDIR%\Microsoft.NET\assembly and you there you can find GAC folder.

How to install Strongly named assembly inside Global Assembly Cache?

Add new Class library project to Solution and name it AssemblyToInstall and strong name it.

Drag and drop approach:

Just simple locate bin\Debug folder inside AssemblyToInstall project, locate AssemblyToInstall.dll file and drop it to appropriate location (C:\Windows\Microsoft.NET\assembly). Note that you can do this only if your user has elevated privileges.

Using GacUtil.exe

If you are using Visual Studio 2013 or 2015 version, you can search for Developer Command Prompt and run it as Administrator.

New console will open.

Navigate to project. Mine is located on D drive under charp folder

Next you will need to run gacutil toll with -i parameter (basically -i switch is telling gacutil that we want to install assembly) followed by Assembly dll we want to install.

run command: gacutil.exe -i AssemblyToInstall.dll

GAC

How to use gacutil to install strongly named assembly inside GAC folder

You should receive message: “Assembly successfully added to the cache”

If you receive message: “Failure adding assembly to the cache: Attempt to install an assembly without a strong name”. That means that you have not signed assembly.

Now navigate to %WINDIR%\Microsoft.NET\assembly\GAC_MSIL\AssemblyToInstall and there you can see your assembly and can use that path to provide reference to that assembly to all applications located on this machine.

Tomorrow we will continue with topic on how to implement side-by-side hosting.

Strongly named assemblies

Purpose of strong naming assemblies is to create unique identity for desired assembly. You would typically want to do that when you need multiple versions of same assembly to be used, when assembly must be installed inside GAC (global assembly cache) or when you want assemblies to be to be referenced by strongly named assemblies.

What does it mean to be strongly named?

Strongly named assemblies are assemblies that have:

Name (usually name of project)

AssemblyVersion (AssemblyVersion information)

Culture information (Assemblies are usually culture neutral but if you wish to change them you can access AssemblyInfo.cs file and change AssemblyCulture attribute)

Private/Public key token (main difference between strongly named assemblies and weakly named assemblies)

I wish to create strongly named assemblies! What do i do?

First you would create a project. That first step would create weakly named assembly. Next what you want to do is sign it. There are multiple ways to achieve this.

First Approach:

From Visual studio:

  1. Right click project
  2. Properties
  3. Select Signing tab
  4. Check “Sign the assembly” CheckBox
  5. From Drop-down control select New
  6. Input necessary Information
  7. Select Drop-down control again and find your  .pfx file

Strongly named assemblies

How to strongly name assemblies

Now when we know how to strong name assemblies we can continue to part on how to put an assembly in the global assembly cache.

 

 

Version assemblies

When talking about Version assemblies you would usually interact with AssemblyVersion, AssemblyFileVersion, AssemblyInformationalVersion Atrributes. Ability to successfully version assemblies is important while testing, debugging and deploying your assemblies. Why? Because it allows you and your team to inspect and debug same version of assemblies on one hand and to know what version of assemblies is are your customers using when talking about future requirements and current problems.

AssemblyVersion and AssemblyFileVersion

attributes

Can be manually located in your Solution explorer:

AssemblyInfo.cs

AssemblyInfo.cs file you can manually change values of a few Attributes. But now we will take look at AssemblyVersion and AssemblyFileVersion attributes. Both these Attributes provide default value in string format. Default values  should appear like this when you initially create project:

Number values inside string have specific meaning:

  1. value -> major value. Value should be changed when changes to your program are noticeable, like major User interface and under the hood changes
  2. value -> minor. increment this value when adding new capabilities to your Application.
  3. value -> build number. Obviously this value should be incremented when running a build
  4. value -> revision. Value that you should increment when choosing which build version to deploy

Build number and revision can be automated by using asterisk(*). Just change strings too look like this and their values will be incremented automatically after each build:

If you are developing small scale application it is best to change minor and major values manually.

AssemblyVersion attribute is used by other assemblies. When value of this attribute is changed, all assemblies that reference it must change value to match current value to ensure that communication between them will proceed uninterrupted.

AssemblyFileVersion attribute is used for deployment (when you ship assemblies to end user). You always need to know which version of assembly is shipped to your customer so that you can assist them, detect bugs and plan future changes.

AssemblyInformationalVersion

Usually you would not like to bore or even worse scare customers by displaying version of your Application in format like 8.56.7520.1459. You will want to display assembly version in user friendly format like 8.56 RC or 8 Orange, or any other format that will appeal to end user. This is where AssemblyInformationalVersion steps in. We can declare AssemblyInformationalVersion inside AssemblyInfo.cs file.

Nice. Please show me how to access these values.

First of. make sure that your AssemblyInfo.cs files has following values:

And inside main Method put following code:

This post has thought you how to version assemblies and was first post in Manage assemblies topic. Now we will continue to topic on how to strong name your assembly.

Streams

 Streams are sequence of bytes that you can use to read from or write to a backing store.

Let’s break down last sentence into a few parts:

  1. „Stream is a sequence of bytes“ – When working with data it is preferable that we read data in chunks of bytes. By breaking data in chunks we do not have to wait for our application to retrieve all parts of a data. For example, we may be accessing a audio file from network location and we want to process that audio file. Retrieving that file would take time and our application would need to wait until retrieval process is done before it can do some job. When using Streams we can specify how large chunks will be. You have seen this example: when listening to a music from popular music streaming site you will see information about bit-rate, that bit-rate represents chunk of data that is downloaded to you device for consumption.
  2. „that you can use to read from or write“ – Stream allows us to read, write or both to a storage device.
  3. „to a backing store“ – backing store represents your local Hard drive, memory, network location or any type of storage medium.

System class in System.IO namespace is a base class for all streams.

When using streams type of file (.txt, .mp3, .mkv, .doc, …) does not matter because it will be transformed to a sequence of bytes and your job is to convert that sequence to a meaningful representation of data. Retrieving data from a backing store will store data in a memory so you can use it in your application.

Every backing store type has appropriate streaming class for reading and writing operations. These streams are called Base Streams retrieve bytes. To consume:

  • FileSytem (local Hard drive, usbv drive…) you would use FileStream
  • Local memory -> MemoryStream
  • Remote location (Internet, Local network) -> NetworkStream

You use Stream Adapters allow you to transform bytes to types you would usually use in your application, such as integers and strings, by giving you access to classes and methods to consume data. Most commonly used are:

  • StreamReader/StreamWriter
  • BinaryReader/BinaryWriter
  • XmlReader/XmlWriter

For Streams to know where is beginning, current position, and end of a stream, pointer is used. Default position of pointer is at the beginning of a stream, or poistion 0. Streaming ends when pointer hits last position in a stream.

Example:

Lets say that we need to read 10 bytes which will be redistributed to positions 0-9, and we read data in chunks of 4 bytes. First we will read first 4 bytes and pointer will be at the position 3, then next four bytes are read and position will move to 7 and finally last two bytes will be read an pointer will be moved to position 9 and stream will end because end of stream is reached.

Caution! Sometimes, mostly while using network streams, when we expect stream to retrieve certain number of bytes we will not retrieve them all, so be careful when reading or writing data and always check if all bytes are written or read.

Is it possible to set pointer at certain position of a stream?

Yes it is, that process is called seeking. Note that MemoryStream andFile stream support it but NetworkStream does not. Also seeking allows us to read from beginning, end or custom location from within a stream.

Do I have to dispose of a Streams?

Yes, you should always dispose of a stream or or use using statement.

This conclude introduction to Streams lets see some examples.

Example of using FileStream:

 

 

Assembly class

Assembly class allows us to:

  • Load assemblies
  • Explore metadata and types
  • Create instance of types

Easiest way to load assembly is by load them using following methods :

GetAssembly (requires Type variable)

GetCallingAssembly (returns Assembly from which this method has been called)

These two methods have Assembly return type. After acquiring Assembly variable we can use it to get types that we want using GetType method.

Let’s explore Assembly class:

 

© 2019 LearnC#WithDarko

Theme by Anders NorenUp ↑