WCF---预备知识

来源:互联网 发布:浙江软件企业行业协会 编辑:程序博客网 时间:2024/06/09 23:42

为了能正确理解并有效使用WCF,必须熟悉.NET Framework2.0和>NET CLR的一些功能特性。

----摘自  Windows Communication Foundation Unleashed 

分部类 (通俗来说 就是部分类)

Microsoft Visual C# 2005开始允许一个类的定义由多个部分定义组成。这些部分定义可以分布到任意多个属于同一模块的源代码文件中。可以通过修饰符partial使用这个特性。即在类、接口、结构定义前添加该修饰符。

泛型

微软文档这样定义泛型:
泛型(generic)是这样的一些类、结构、接口和方法,它们为其存储或使用的一个或多个类型提供占位符。下面是泛型的例子
public calss List<T> 
该类有这样一个方法:
public Add(T item);
其中T就是泛型类System.Collections.Generic.List<T>的实例所存储类型的占位符。在泛型类的实例定义中,必须指定这个实例存储的实际类型:
List<string> myListOfStrings = new List<string>();
然后就可以使用该泛型实例的Add()方法了;
myListOfStrings.Add("Hello World");

System.Collections.Generic.List<T>类被称为泛型类型定义(generic type definition).
占位符T被称为泛型类型形参(generic type parameter)。 例如下面这个生命:
List<string> myListOfStrings;
将System.Collenctions.Generic.List<string>变成已构造类型(constructed type),而string被称为一个泛型类型实参(generic type augument)。

泛型的设计者可以使用约束来限制作为泛型类型实参的类型。下面这个类型定义:
public class MyGenericType<T> where T:new(),IComprable
将泛型类型实参的类型限制为具有公共的无参构造函数并且实现了IComprable接口的类型

下面这个限制更加宽松:
public class MyGenericType<T> where T:class
只是将泛型类型实参限制为一个类。

泛型和非泛型类型都可以具有泛型方法。下面是一个具有泛型方法的非泛型类型的例子:
using System;
public class Printer
{
public void Print<T>(T argument)
{
Console.WriteLine(argument.ToString());
}
static void Main(string[] arguments)
{
Printer printer =new Printer();
printer.Print<string>("Hello World");
Console.ReadKey();
}
}
在泛型编程中,经常需要判断替代泛型类型的泛型实参的类型。下面的例子,显示如何进行这样的判断
public class Printer
{
public void Print<T>(T argument)
{
if(typeof(T)==typeof(string))
{
Console.WriteLine(argument);
}
else
{
Console.WriteLine(argument.ToString());
}
}
static void Main(string[] arguments)
{
Printer printer =new Printer();
printer.Print<string>("Hello World");
Console.ReadKey();
}
}
一个泛型接口可以由泛型类型或非泛型类型实现。同样泛型类型和非泛型类型都可以继承自泛型基类型。

可空值类型

.NET Framework 2.0包含了一个泛型类型定义,它满足这两种情况的要求:
可以讲一个值类型的实例赋值成null,并且可以判断该实例的值是否为null。该泛型类型定义就是System.Nullable<T>,其中T被显示为值类型。从System.Nullable<T>构造而来的类型实例可以赋值成null,实际上,他们的默认值就是null。所以,从System.Nullable<T>构造而来的类型称为可空值类型(nullable value type)。

System.Nullable<T>有一个属性Value,当一个可空类型实例的值补位null时,可以通过这个属性获得该实例类型的值。所以,我们可以写出类似下面这样的代码:
System.Nullable<int> myNullableInteger =null;
myNullableInteger =1 ;
if(myNullableInteger !=null)
{
Console.WriteLine(myNullableInteger.Value);
}
C#提供了一种简化的语法来声明从System.Nullable<T>构造的类型。
即:System.Nullable<int> myNullableInteger;  简写成int? myNullableInteger;

因为可空值类型的值是可以为null的,所以这个值不可以赋给普通值类型。虽然编译器对下面的代码不报错:
int? myNullableInteger =null ;
int myInteger = myNullableInteger.Value;
但是第二行代码运行时将会抛出异常,因为从System.Nullable<T>构造的类型没有赋予一个有效的T类型值,任何对其System.Nullable<T>.Value属性的访问都是无效操作。
将一个可空值类型的值赋值给普通值类型的方法时先用System.Nullable<T>.HasValue属性判断这个可控制类型是否被赋过一个类型为T的有效值。
int? myNullableInteger =null ;
if(myNullableInteger.HasValue)
{
int myInteger = myNullableInteger.Value;
}
另外一种方法是:
myInteger = myNullableInteger ?? -1;
如果myNullableInteger 为null 取-1 ,不为null则赋值。

轻量级事务管理器

在计算机领域,事务是一种离散动作---该动作要么全部完成,要么什么都不做。如果在某个资源上发起的事务没有全部完成,则由资源管理器确保资源恢复到事务开始之前的状态。分布式事务会跨越多个资源,所以会涉及多个资源管理器。Windows操作系统在多年前就已经加入了一个分布式事务管理器,即Microsoft分布式事务协调器(Microsoft Distributed Transaction Coordinator)。

.NET Framework1.0和1.1版本提供了两种事务编程的方法。
一种是ADO.NET提供的抽象类System.Data.Common.DBConnection定义了一个BeginTransaction()方法,通过该方法可以开始一个事务,而该事务是由DbConnection的具体实现所提供的资源管理器来控制的。
另一种方法时由Enterprise Services提供额,他提供了System.EnterpriseServices.Transaction特性,任何System.EnterpriseServices.ServicedComponent的子类都可以添加这特性,从而隐式的将其任何方法中的任何正在执行的代码加入到一个由Microsoft分布式事务处理协调器管理的事务中。

使用ADO.NET的方法,事务由单一的资源管理器处理,而使用Enterprise Services的方法时,无论事务是否为分布式,Microsoft分布式事务处理协调器总是会被使用,从而增加了额外开销。

.NET 2.0引入了轻量级事务管理器(Lightweight Transaction Manager).即System.Transactions.TransactionManager。轻量级事务管理器具有最小的开销。
如果一个事务里只有一个资源管理器,轻量级事务管理器可以让资源管理器来管理该事务,而轻量级事务管理器只负责监视他。如果轻量级事务管理器发现有另外一个资源管理器加入到事务中,轻量级事务管理器则会让原来的资源管理器释放控制权,并将控制权转移给分布式事务处理协调器。将控制权在事务还在进行时转移给分布式事务处理协调器的这个过程称为事务升级(promotion of a transaction)。
System.Transation命名空间允许显氏或者隐式的使用轻量级事务管理器进行事务编程。下面的例子展示了如何显示的使用System.Transaction.CommitableTransaction类:
CommitableTransation transation = new CommitableTransation();
using(SqlConnection con =new SqlConnection(conString))
{
con.open()
con.EnlistTransation(tx);

//进行事务操作
//提交事务

transaction.Close();
}
隐式的方法会使用System.Transaction.TransactionScope类(该方法比较灵活)
using(TransactionScope scope =new TransactionScope())
{
//事务操作

//如果没有错误,提交事务

scope.Complete();
}
在System.Transactions.TransactionScope 实例的using块中执行的代码会隐式的包含到一个事务中。这也是为什么该事务编程方式被称作隐式的原因。
System.Transactions.TransactionScope实例的Complete方法只能被调用一次。如果塔被调用了,事务就会被提交。
原创粉丝点击