Tuesday 19 July 2011

Windows Communication Foundation Architecture Overview


Contents

Introduction
WCF Fundamentals
Code Examples
Summary

Introduction

This document provides a high-level view of the Windows Communication Foundation (WCF) architecture. It is intended to explain key concepts in WCF and how they fit together. There are a few code examples to further illustrate the concepts, but code is not the emphasis of this document.
The rest of this document is organized in two main sections:
  • WCF Fundamentals: Covers key concepts in WCF, terms, and architectural components.
Code Examples: Provides a few short code examples intended to illustrate and reify the concepts covered in WCF Fundamentals.


WCF Fundamentals

A WCF Service is a program that exposes a collection of Endpoints. Each Endpoint is a portal for communicating with the world.
A Client is a program that exchanges messages with one or more Endpoints. A Client may also expose an Endpoint to receive Messages from a Service in a duplex message exchange pattern.
The following sections describe these fundamentals in more detail.

Endpoints

A Service Endpoint has an Address, a Binding, and a Contract.
The Endpoint's Address is a network address where the Endpoint resides. The EndpointAddress class represents a WCF Endpoint Address.
The Endpoint's Binding specifies how the Endpoint communicates with the world including things like transport protocol (e.g., TCP, HTTP), encoding (e.g., text, binary), and security requirements (e.g., SSL, SOAP message security). The Binding class represents a WCF Binding.
The Endpoint's Contract specifies what the Endpoint communicates and is essentially a collection of messages organized in operations that have basic Message Exchange Patterns (MEPs) such as one-way, duplex, and request/reply. The ContractDescription class represents a WCF Contract.
The ServiceEndpoint class represents an Endpoint and has an EndpointAddress, a Binding, and a ContractDescription corresponding to the Endpoint's Address, Binding, and Contract, respectively



EndpointAddress

An EndpointAddress is basically a URI, an Identity, and a collection of optional headers as shown in Figure 2.
An Endpoint's security identity is normally its URI; however, in advanced scenarios the identity can be explicitly set independent of the URI using the Identity address property.
The optional headers are used to provide additional addressing information beyond the Endpoint's URI. For example, address headers are useful for differentiating between multiple Endpoints that share the same address URI.


Bindings

A Binding has a name, a namespace, and a collection of composable binding elements (Figure 3). The Binding's name and namespace uniquely identify it in the service's metadata. Each binding element describes an aspect of how the Endpoint communicates with the world.

For example, Figure 4 shows a binding element collection containing three binding elements. The presence of each binding element describes part of the how of communicating with the Endpoint. The TcpTransportBindingElement indicates that the Endpoint will communicate with the world using TCP as the transport protocol. ReliableSessionBindingElement indicates that the Endpoint uses reliable messaging to provide message delivery assurances. SecurityBindingElement indicates that the Endpoint uses SOAP message security. Each binding element usually has properties that further describe the specifics of the how of communicating with the Endpoint. For example, the ReliableSessionBindingElement has an Assurances property that specifies the required message delivery assurances, such as none, at least once, at most once, or exactly once.

The order and types of binding elements in Bindings are significant: The collection of binding elements is used to build a communications stack ordered according to the order of binding elements in the binding elements collection. The last binding element to be added to the collection corresponds to the bottom component of the communications stack, while the first one corresponds to the top component. Incoming messages flow through the stack from the bottom upwards, while outgoing messages flow from the top downwards. Therefore the order of binding elements in the collection directly affects the order in which communications stack components process messages. Note that WCF provides a set of pre-defined bindings that can be used in the majority of scenarios instead of defining custom bindings.

Contracts

A WCF Contract is a collection of Operations that specifies what the Endpoint communicates to the outside world. Each operation is a simple message exchange, for example one-way or request/reply message exchange.
The ContractDescription class is used to describe WCF Contracts and their operations. Within a ContractDescription, each Contract operation has a corresponding OperationDescription that describes aspects of the operation such as whether the operation is one-way or request/reply. Each OperationDescription also describes the messages that make up the operation using a collection of MessageDescriptions.

A ContractDescription is usually created from an interface or class that defines the Contract using the WCF programming model. This type is annotated with ServiceContractAttribute and its methods that correspond to Endpoint Operations are annotated with OperationContractAttribute. You can also build a ContractDescription by hand without starting with a CLR type annotated with attributes.
A duplex Contract defines two logical sets of operations: A set that the Service exposes for the Client to call and a set that the Client exposes for the Service to call. The programming model for defining a duplex Contract is to split each set in a separate type (each type must be a class or an interface) and annotate the contract that represents the service's operations with ServiceContractAttribute, referencing the contract that defines the client (or callback) operations. In addition, ContractDescription contains a reference to each of the types thereby grouping them into one duplex Contract.
Similar to Bindings, each Contract has a Name and Namespace that uniquely identify it in the Service's metadata.
Each Contract also has a collection of ContractBehaviors that are modules that modify or extend the contract's behavior. The next section covers behaviors in more detail.

Behaviors

Behaviors are types that modify or extend Service or Client functionality. For example, the metadata behavior that ServiceMetadataBehavior implemented controls whether the Service publishes metadata. Similarly, the security behavior controls impersonation and authorization, while the transactions behavior controls enlisting in and auto-completing transactions.
Behaviors also participate in the process of building the channel and can modify that channel based on user-specified settings and/or other aspects of the Service or Channel.
A Service Behavior is a type that implements IServiceBehavior and applies to Services. Similarly, a Channel Behavior is a type that implements IChannelBehavior and applies to Client Channels.

Service and Channel Descriptions

The ServiceDescription class is an in-memory structure that describes a WCF Service including the Endpoints exposed by the Service, the Behaviors applied to the Service, and the type (a class) that implements the Service (see Figure 6). ServiceDescription is used to create metadata, code/config, and channels.
You can build this ServiceDescription object by hand. You can also create it from a type annotated with certain WCF attributes, which is the more common scenario. The code for this type can be written by hand or generated from a WSDL document using a WCF tool called svcutil.exe.
Although ServiceDescription objects can be created and populated explicitly, they are often created behind the scenes as part of running the Service.

Similarly on the client side, a ChannelDescription describes a WCF Client's Channel to a specific Endpoint (Figure 7). The ChannelDescription class has a collection of IchannelBehaviors, which are Behaviors applied to the Channel. It also has a ServiceEndpoint that describes the Endpoint with which the Channel will communicate.
Note that, unlike ServiceDescription, ChannelDescription contains only one ServiceEndpoint that represents the target Endpoint with which the Channel will communicate.

WCF Runtime

The WCF Runtime is the set of objects responsible for sending and receiving messages. For example, things like formatting messages, applying security, and transmitting and receiving messages using various transport protocols, as well as dispatching received messages to the appropriate operation, all fall within the WCF runtime. The following sections explain the key concepts of the WCF runtime.

Message

The WCF Message is the unit of data exchange between a Client and an Endpoint. A Message is essentially an in-memory representation of a SOAP message InfoSet. Note that Message is not tied to text XML. Rather, depending on which encoding mechanism is used, a Message can be serialized using the WCF binary format, text XML, or any other custom format.

Channels

Channels are the core abstraction for sending Messages to and receiving Messages from an Endpoint. Broadly speaking, there are two categories of Channels: Transport Channels handle sending or receiving opaque octet streams using some form of transport protocol such as TCP, UDP, or MSMQ. Protocol Channels, on the other hand, implement a SOAP-based protocol by processing and possibly modifying messages. For example, the security Channel adds and processes SOAP message headers and may modify the body of the message by encrypting it. Channels are composable such that a Channel may be layered on top of another Channel that is in turn layered on top of a third Channel.

EndpointListener

An EndpointListener is the runtime equivalent of a ServiceEndpoint. The EndpointAddress, Contract, and Binding of ServiceEndpoint (representing where, what and how), correspond to the EndpointListener's listening address, message filtering and dispatch, and channel stack, respectively. The EndpointListener contains the Channel stack that is responsible for sending and receiving messages.

ServiceHost and ChannelFactory

The WCF Service runtime is usually created behind the scenes by calling ServiceHost.Open. ServiceHost (Figure 6) drives the creation of a ServiceDescription from on the Service type and populates the ServiceDescription's ServiceEndpoint collection with Endpoints defined in config or code, or both. ServiceHost then uses the ServiceDescription to create the channel stack in the form of an EndpointListener object for each ServiceEndpoint in the ServiceDescription.

Similarly, on the client side, the Client runtime is created by a ChannelFactory, which is the Client's equivalent of ServiceHost.
ChannelFactory drives the creation of a ChannelDescription based on a Contract type, a Binding, and an EndpointAddress. It then uses this ChannelDescription to create the Client's channel stack.
Unlike the Service runtime, the Client runtime does not contain EndpointListeners because a Client always initiates connection to the Service, so there is no need to "listen" for incoming connections.

Code Examples

This section provides code examples that show how Services and Clients are built. These examples are intended to reify the above concepts and not to teach WCF programming.

Defining and Implementing a Contract

As mentioned above, the easiest way to define a contract is creating an interface or a class and annotating it with ServiceContractAttribute, allowing the system to easily create from it a ContractDescription.
When using interfaces or classes to define contracts, each interface or class method that is a member of the contract must be annotated with OperationContractAttribute. For example:
using System.ServiceModel;
 
//a WCF contract defined using an interface
[ServiceContract]
public interface IMath
{
    [OperationContract]
    int Add(int x, int y);
}
Implementing the contract in this case is simply a matter of creating a class that implements IMath. That class becomes the WCF Service class. For example:
//the service class implements the interface
public class MathService : IMath
{
    public int Add(int x, int y)
    { return x + y; }
}

Defining Endpoints and Starting the Service

Endpoints can be defined in code or in config. In the example below, the DefineEndpointImperatively method shows the easiest way to define Endpoints in code and start the service.
DefineEndpointInConfig method shows the equivalent endpoint defined in config (config example follows the code below).
public class WCFServiceApp
{
    public void DefineEndpointImperatively()
    {
        //create a service host for MathService
        ServiceHost sh = new ServiceHost(typeof(MathService));
 
        //use the AddEndpoint helper method to
        //create the ServiceEndpoint and add it 
        //to the ServiceDescription
        sh.AddServiceEndpoint(
          typeof(IMath), //contract type
          new WSHttpBinding(), //one of the built-in bindings
          "http://localhost/MathService/Ep1"); //the endpoint's address
 
        //create and open the service runtime
        sh.Open();
 
    }
 
    public void DefineEndpointInConfig()
    {
        //create a service host for MathService
        ServiceHost sh = new ServiceHost (typeof(MathService));
 
        //create and open the service runtime
        sh.Open();
 
    }
}
<!-- configuration file used by above code -->
<configuration 
   xmlns="http://schemas.microsoft.com/.NetConfiguration/v2.0">
   <system.serviceModel>
      <services>
                 <!-- service element references the service type -->
         <service type="MathService">
            <!-- endpoint element defines the ABC's of the endpoint -->
              <endpoint 
            address="http://localhost/MathService/Ep1"
            binding="wsHttpBinding"
              contract="IMath"/>
         </service>
      </services>
   </system.serviceModel>
</configuration>

Sending Messages to an Endpoint

The code below shows two ways to send a message to the IMath endpoint. SendMessageToEndpoint hides the Channel creation, which happens behind the scenes while the SendMessageToEndpointUsingChannel example does it explicitly.
The first example in SendMessageToEndpoint uses a tool named svcutil.exe and the Service's metadata to generate a Contract (IMath in this example), a proxy class (MathProxy in this example) that implements the Contract, and associated config (not shown here). Again, the Contract defined by IMath specifies the what (i.e., the operations that can be performed), while the generated config contains a Binding (the how) and an address (the where).
Using this proxy class is simply a matter of instantiating it and calling the Add method. Behind the scenes, the proxy class will create a Channel and use that to communicate with the Endpoint.
The second example in SendMessageToEndpointsUsingChannel below shows communicating with an Endpoint using ChannelFactory directly. In this example, instead of using a proxy class and config, a Channel is created directly using ChannelFactory<IMath>.CreateChannel. Also, instead of using config to define the Endpoint's address and Binding, the ChannelFactory<IMath> constructor takes those two pieces of information as parameters. The third piece of information required to define an Endpoint, namely the Contract, is passed in as the type T.
using System.ServiceModel;
//this contract is generated by svcutil.exe
//from the service's metadata
public interface IMath
{
    [OperationContract]
    public int Add(int x, int y)
    { return x + y; }
}
 
 
//this class is generated by svcutil.exe
//from the service's metadata
//generated config is not shown here
public class MathProxy : IMath
{
    ...
}
 
public class WCFClientApp
{
    public void SendMessageToEndpoint()
    {
        //this uses a proxy class that was
        //created by svcutil.exe from the service's metadata
        MathProxy proxy = new MathProxy();
 
        int result = proxy.Add(35, 7);
    }
    public void SendMessageToEndpointUsingChannel()
    {
        //this uses ChannelFactory to create the channel
        //you must specify the address, the binding and 
        //the contract type (IMath)
        ChannelFactory<IMath> factory=new ChannelFactory<IMath>(
            new WSHttpBinding(),
            new EndpointAddress("http://localhost/MathService/Ep1"));
        IMath channel=factory.CreateChannel();
        int result=channel.Add(35,7);
        factory.Close();
 
    }
}

Defining a Custom Behavior

Defining a custom Behavior is a matter of implementing IServiceBehavior (or IChannelBehavior for client-side behaviors). The code below shows an example behavior that implements IServiceBehavior. In IServiceBehavior.ApplyBehavior, the code inspects the ServiceDescription and writes out the Address, Binding, and Contract of each ServiceEndpoint, as well as the name of each Behavior in the ServiceDescription.
This particular behavior is also an attribute (inherits from System.Attribute), making it possible to apply declaratively as will be shown below. However, behaviors are not required to be attributes.
[AttributeUsageAttribute(
         AttributeTargets.Class,
         AllowMultiple=false,
         Inherited=false)]
public class InspectorBehavior : System.Attribute, 
                                 System.ServiceModel.IServiceBehavior
{
   public void ApplyBehavior(
       ServiceDescription description,
       Collection<DispatchBehavior> behaviors)
   {
       Console.WriteLine("-------- Endpoints ---------");
       foreach (ServiceEndpoint endpoint in description.Endpoints)
       {
           Console.WriteLine("--> Endpoint");
           Console.WriteLine("Endpoint Address: {0}", 
                             endpoint.Address);
           Console.WriteLine("Endpoint Binding: {0}", 
                             endpoint.Binding.GetType().Name);
           Console.WriteLine("Endpoint Contract: {0}", 
                              endpoint.Contract.ContractType.Name);
           Console.WriteLine();
       }
       Console.WriteLine("-------- Service Behaviors --------");
       foreach (IServiceBehavior behavior in description.Behaviors)
       {
           Console.WriteLine("--> Behavior");
           Console.WriteLine("Behavior: {0}", behavior.GetType().Name);
           Console.WriteLine();
       }
   }
}

Applying a Custom Behavior

All behaviors can be applied imperatively by adding an instance of the behavior to the ServiceDescription (or the ChannelDescription on the client side). For example, to apply the InspectorBehavior imperatively you would write:
ServiceHost sh = new ServiceHost(typeof(MathService));
sh.AddServiceEndpoint(
       typeof(IMath), 
        new WSHttpBinding(),
       "http://localhost/MathService/Ep1"); 
//Add the behavior imperatively
InspectorBehavior behavior = new InspectorBehavior();
sh.Description.Behaviors.Add(behavior);
sh.Open();
Additionally, behaviors that inherit from System.Attribute may be applied declaratively to the service. For example, because InspectorBehavior inherits from System.Attribute, it can be applied declaratively like this:
[InspectorBehavior]
public class MathService : IMath
{
   public int Add(int x, int y)
   { return x + y; }
}

Summary

WCF Services expose a collection of Endpoints where each Endpoint is a portal for communicating with the world. Each Endpoint has an Address, a Binding, and a Contract (ABC). The Address is where the Endpoint resides, the Binding is how the Endpoint communicates, and the Contract is what the Endpoint communicates.
On the Service, a ServiceDescription holds the collection of ServiceEndpoints each describing an Endpoint that the Service exposes. From this description, ServiceHost creates a runtime that contains an EndpointListener for each ServiceEndpoint in the ServiceDescription. The Endpoint's address, Binding, and Contract (representing the where, what, and how) correspond to the EndpointListener's listening address, message filtering and dispatch, and channel stack, respectively.
Similarly, on the Client, a ChannelDescription holds the one ServiceEndpoint with which the Client communicates. From this ChannelDescription, ChannelFactory creates the channel stack that can communicate with the Service's Endpoint.

Tuesday 5 July 2011

Sql Helper Class

using System;
using System.Data;
using System.Data.SqlClient;
using System.Configuration;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace MyClassLibrary.DAL
{
    public class Database : IDisposable
    {
        private SqlConnection connection = null;
        private String connectionString = "dbConnection";
        public String ConnectionString
        {
            set { connectionString = value; }
        }
        #region Constructors
        /// <summary>
        /// Default Constructor.
        /// </summary>
        public Database() { }
        /// <summary>
        /// Parameteraize constructor. It takes connection string as parameter.
        /// </summary>
        /// <remarks>If connection string is not specified then Default connection string is "dbConnection"</remarks>
        /// <param name="p_connectionString"></param>
        public Database(string p_connectionString) { if (!string.IsNullOrEmpty(p_connectionString.Trim()))connectionString = p_connectionString; }
        #endregion
        #region AddParameter Methods
        private void AddParameter(SqlCommand command, string parameterName, SqlDbType dbType, int size, ParameterDirection direction,
            byte precision, byte scale, string sourceColumn, DataRowVersion sourceVersion, object value)
        {
            SqlParameter p = new SqlParameter(parameterName, dbType, size, direction, precision, scale, sourceColumn,
                sourceVersion, true, value, null, null, null);
            command.Parameters.Add(p);
        }
        public void AddParameter(SqlCommand command, string parameterName, SqlDbType dbType, int size, ParameterDirection direction, object value)
        {
            AddParameter(command, parameterName, dbType, size, direction, 0, 0, null, DataRowVersion.Current, value);
        }
        public void AddInParameter(SqlCommand command, string parameterName, SqlDbType dbType, object value)
        {
            AddParameter(command, parameterName, dbType, 0, ParameterDirection.Input, value);
        }
        public void AddOutParameter(SqlCommand command, string parameterName, SqlDbType dbType, int size)
        {
            AddParameter(command, parameterName, dbType, size, ParameterDirection.Output, null);
        }
        public object GetParameterValue(SqlCommand command, string parameterName)
        {
            return command.Parameters[parameterName].Value;
        }
        #endregion
        #region Methods for Generating SqlCommand
        private SqlCommand PrepareCommand(CommandType commandType, string commandText)
        {
            if (connection == null)
            {
                string _connectionString = ConfigurationManager.ConnectionStrings[connectionString].ConnectionString;
                connection = new SqlConnection(_connectionString);
            }
            if (connection.State == ConnectionState.Closed || connection.State == ConnectionState.Broken)
            {               
                connection.Open();
            }
            SqlCommand command = new SqlCommand(commandText, connection);
            command.CommandType = commandType;
            return command;
        }
        public SqlCommand GetStoreProcedureCommand(string spname)
        {         
            return PrepareCommand(CommandType.StoredProcedure, spname);
        }
        public SqlCommand GetSqlQueryCommand(string query)
        {
            return PrepareCommand(CommandType.Text, query);
        }
        #endregion
        #region Database Related Command Methods
        public int ExecuteNonQuery(SqlCommand command)
        {
            return command.ExecuteNonQuery();
        }
        public object ExecuteScalar(SqlCommand command)
        {
            return command.ExecuteScalar();
        }
        public SqlDataReader ExecuteReader(SqlCommand command)
        {
            return command.ExecuteReader(CommandBehavior.CloseConnection);
        }
        public SqlDataReader ExecuteReader(SqlCommand command, CommandBehavior commandBehavior)
        {
            return command.ExecuteReader(commandBehavior);
        }
        public DataTable LoadDataTable(SqlCommand command, string tableName)
        {
            using (SqlDataAdapter da = new SqlDataAdapter(command))
            {
                DataTable dt = new DataTable(tableName);
                da.Fill(dt);
                return dt;
            }
        }
        public DataSet LoadDataSet(SqlCommand command, string[] tableNames)
        {
            using (SqlDataAdapter da = new SqlDataAdapter(command))
            {
                DataSet ds = new DataSet();
                da.Fill(ds);
                for (int i = 0; i < ds.Tables.Count; i++)
                {
                    ds.Tables[i].TableName = tableNames[i];
                }
                return ds;
            }
        }
        #endregion
        #region Methods for Transaction Handling
        private SqlTransaction PrepareTransaction(IsolationLevel isolationLevel)
        {
            if (connection == null)
            {
                string _connectionString = ConfigurationManager.ConnectionStrings[connectionString].ConnectionString;
                connection = new SqlConnection(_connectionString);
            }
            if (connection.State == ConnectionState.Closed || connection.State == ConnectionState.Broken)
            {
                connection.Open();
            }
            return connection.BeginTransaction(isolationLevel);
        }
        public SqlTransaction BeginTransaction()
        {
            return PrepareTransaction(IsolationLevel.ReadCommitted);
        }
        public SqlTransaction BeginTransaction(IsolationLevel isolationLevel)
        {
            return PrepareTransaction(isolationLevel);
        }
        public void Commit(SqlTransaction transaction)
        {
            if (transaction != null)
                transaction.Commit();
        }
        public void RollBack(SqlTransaction transaction)
        {
            if (transaction != null)
                transaction.Rollback();
        }
        #endregion
        #region IDisposable Members
        public void Dispose()
        {
            GC.SuppressFinalize(this);
        }
        #endregion
        ~Database()
        {
            Dispose();
        }
    }

F# (F Sharp)

F# (pronounced F Sharp) is a multi-paradigm programming language, targeting the .NET Framework, that encompasses functional programming as well as imperative and object-oriented programming disciplines. It is a variant of ML and is largely compatible with the OCaml implementation. F# was initially developed by Don Syme at Microsoft Research but is now being developed at Microsoft Developer Division and is being distributed as a fully supported language in the .NET Framework and Visual Studio as part of Visual Studio 2010.
F# is a strongly typed language that uses type inference. As a result, data types need not be explicitly declared by the programmer; they will be deduced by the compiler during compilation. However, F# also allows explicit data type declaration. Being a CLI compliant language, F# supports all CLI types and objects but it extends the type system and categorizes types as immutable types or mutable types. CLI objects classify as mutable types (which can be edited in-place), and are used to provide an object-oriented programming model. Immutable types (editing such a type creates a new instance without overwriting the older one) are primarily used for functional programming.
Like ML, F# includes a functional programming component supporting eager evaluation. For functional programming, it provides several constructs and a set of immutable types: tuples, records, discriminated unions and lists.[3]
An n-tuple represents a collection of n values, where n ≥ 0. The value n is called the arity of the tuple. The type unit corresponds to the 0-tuple and it has one value only: (), which conveys no information. The type unit is used to implement functions that need no input and/or return no value. A 3-tuple would be represented as (A, B, C), where A, B and C are values of possibly different types. A tuple can be used only to store values when the number of values is known at design-time and stays constant throughout execution.
A record is a specialization of tuple where the data members are named, as in { Name:string; Age:int }. Records can be created as { Name="AB"; Age=42 }. The with keyword is used to create a copy of a record, as in { r with Name="CD" }, which creates a new record by copying r and changing the value of the Name field (assuming the record created in the last example was named r).
The list type is a regular linked list represented either using a head::tail notation (:: is the cons operator) or a shorthand as [item1; item2; item3]. An empty list is written [].
The other sort of algebraic data type mentioned, "discriminated unions" (type-safe versions of C unions), can be defined to hold a value of any of a pre-defined type. For example,
 type A =
    | ConstructorX of string
    | ConstructorY of int
can hold values as instantiated by either constructor. The type of the values the constructors will act on can be defined as well.
Constructors are used to create a view of the data type different from the actual implementation, as required for supporting the Active Patterns concept.[3] Data types are created with the type keyword. F# uses the let keyword for binding type values to a name (variable).[3]
F# uses pattern matching to resolve names into values. It is also used when accessing discriminated unions. Functions using a discriminated union provide different expressions to be invoked, associated with the data type in the union. The union is matched against these data types, and the expression associated with the match is invoked. F# also supports the Active Patterns pattern. It is used, for example, when a type needs to provide multiple views. For example, an exponential number will provide both the final value, as well as the base and exponents.[3]
All functions in F# are instances of the function type, and are immutable as well.[3] Functions can either be curried or in uncurried form. Being an instance of a type, functions can be passed as arguments to other functions, resulting in higher order functions. F# supports lambda functions and closures as well.[3] Like other functional programming languages, F# allows function composition using the >> operator. Every statement in F#, including if statements and loops, is a composable expression with a definite return type as well.[3] Functions and expressions that do not return any value have a return type of unit.
The F# extended type system is implemented as generic .NET types. The Record type creates a .NET class with the field names as properties. Tuples are generic classes of type Tuple<_,_>. The number of type parameters define the number and types of the elements in the tuple. Discriminated unions are implemented as tagged unions. Functions are of type FastFunc<_,_> with type parameters specifying the parameter and return types.[4]
F#, like other .NET languages, can use .NET types and objects, using an imperative object-oriented style of programming. For imperative programming, F# supports for and while loops, arrays (created with the [| ... |] syntax, and number sequences written in shorthand as in 1 .. 25) and support for creating Object types (equivalent to .NET classes).[3] F# also allows extending the syntax to support embedding custom domain-specific languages within the F# language itself.[3]
F# provides sequence expressions[5] that allows for a defining a sequence block (seq { ... } or [ ... ] or [| ... |]) encapsulating constructs (either functions, conditional expressions or loops) that act on a collection and another function (or lambda), such that the function is invoked on the results yielded from the collection collection-processing expressions. For example, seq { for b in 0 .. 25 do if b < 15 then yield b*b } is a sequence expression that forms a sequence of squares of numbers from 0 to 14 by filtering out numbers from the range of numbers from 0 to 25. The sequence is lazily evaluated, i. e., the collection is processed and results yielded on-demand. It can be used for filtering and is the basis of support for LINQ queries. Sequence expressions are generalized as Computation Expressions which are equivalent to monads.[5]
Sequence expressions and computation expressions are also used for creating asynchronous workflows.[6] An asynchronous workflow is defined as a sequence of commands inside a async{ ... }, as in
 let asynctask = async
 {
     let req = WebRequest.Create(url)
     let! response = req.GetResponseAsync()
     use stream = response.GetResponseStream()
     use streamreader = new System.IO.StreamReader(stream)
     return streamreader.ReadToEnd()
 }
The let! allows the rest of the async block to be defined as the delegate and passed as the callback function of an asynchronous operation. This helps deal with inversion of control issues.[6] The async block is invoked using the Async.Run function. Multiple async blocks are executed in parallel using the Async.Parallel function that takes a list of async objects (in the example, asynctask is an async object) and creates another async object to run the tasks in the lists in parallel. The resultant object is invoked using Async.Run.[6]
F# comes with a Microsoft Visual Studio language service that integrates it with the IDE. With the language service installed, Visual Studio can be used to create F# projects and the Visual Studio debugger used to debug F# code. In addition, it comes with a Visual Studio-hosted interactive console that executes F# code as it is being written.
Examples
A few small samples follow:
(* This is commented *)
(* Sample hello world program *)
printfn "Hello World!"
A simple example that is often used to demonstrate the syntax of functional languages is the factorial function for non-negative 32-bit integers, here shown in F#:
let rec factorial n =
    match n with
    | 0 -> 1
    | _ -> n * factorial (n - 1)
Recursive function examples:
(* print a list of numbers recursively *)
let rec printList lst =
    match lst with
    | [] -> ()
    | h :: t ->
        printf "%d\n" h
        printList t

(* Same thing, using matching against list elements *)
let rec printList2 l =
    match l with
    | []     -> ()
    | h :: t -> printfn "%A" h
                printList2 t

(* Using shorthand for match *)
let rec printList3 = function
    | []     -> ()
    | h :: t -> printfn "%A" h
                printList3 t

(* Or, using a higher-order function *)
let printlist4 lst = List.iter (printfn "%A") lst
(* Fibonacci Number formula *)
let rec fib n =
    match n with
    | 0 | 1 -> n
    | _ -> fib (n - 1) + fib (n - 2)

(* An alternative approach - a lazy recursive sequence of Fibonacci numbers *)
let rec fibs = Seq.cache <| seq { yield! [1; 1]                                 
                                  for x, y in Seq.zip fibs <| Seq.skip 1 fibs -> x + y }

(* Another approach - a lazy infinite sequence of Fibonacci numbers *)
let fibSeq = Seq.unfold (fun (a,b) -> Some(a+b, (b, a+b))) (1,1)

(* Print even fibs *)
[1 .. 10]
|> List.map     fib
|> List.filter  (fun n -> (n % 2) = 0)
|> printlist

(* Same thing, using sequence expressions *)
[ for i in 1..10 do
    let r = fib i
    if r % 2 = 0 then yield r ]
|> printlist
(* Sample Windows Forms Program *)

(* We need to open the System library for the STAThreadAttribute class *)
open System

(* We need to open the Windows Forms library *)
open System.Windows.Forms

(* Create a window and set a few properties *)
let form = new Form(Visible=true, TopMost=true, Text="Welcome to F#")

(* Create a label to show some text in the form *)
let label =
    let temp = new Label()
    let x = 3 + (4 * 5)
    (* Set the value of the Text*)
    temp.Text <- sprintf "x = %d" x
    (* Remember to return a value! *)
    temp

(* Add the label to the form *)
form.Controls.Add(label)

(* Finally, run the form  *)
[<STAThread>]
Application.Run(form)
(* Async workflows sample (parallel CPU and I/O tasks) *)

(* A very naive prime number detector *)
let isPrime (n:int) =
   let bound = int (System.Math.Sqrt(float n))
   seq {2 .. bound} |> Seq.exists (fun x -> n % x = 0) |> not

(* We are using async workflows *)
let primeAsync n =
    async { return (n, isPrime n) }

(* Return primes between m and n using multiple threads *) 
let primes m n =
    seq {m .. n}
        |> Seq.map primeAsync
        |> Async.Parallel
        |> Async.RunSynchronously
        |> Array.filter snd
        |> Array.map fst

(* Run a test *)
primes 1000000 1002000
    |> Array.iter (printfn "%d")