|
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有帐号?立即注册
x
有理由相信是能提供更出色的性能。很多平台无法支持复杂的编译器,因此需要二次编译来减少本地编译器的复杂度。当然可能做不到java编译器那么简易。Attribute在拦阻机制上的使用
从这一节入手下手我们会商Attribute的初级使用,为此我筹办了一个实践的例子:我们有一个定单处置体系,当一份定单提交的时分,体系反省库存,假如库存存量满意定单的数目,体系纪录定单处置纪录,然后更新库存,假如库存存量低于定单的数目,体系做响应的纪录,同时向库存办理员发送邮件。为了便利演示,我们对例子举行了简化:
//Inventory.cs
usingSystem;
usingSystem.Collections;
namespaceNiwalkerDemo
{
publicclassInventory
{
privateHashtableinventory=newHashtable();
publicInventory()
{
inventory["Item1"]=100;
inventory["Item2"]=200;
}
publicboolCheckout(stringproduct,intquantity)
{
intqty=GetQuantity(product);
returnqty>=quantity;
}
publicintGetQuantity(stringproduct)
{
intqty=0;
if(inventory[product]!=null)
qty=(int)inventory[product];
returnqty;
}
publicvoidUpdate(stringproduct,intquantity)
{
intqty=GetQuantity(product);
inventory[product]=qty-quantity;
}
}
}
//Logbook.cs
usingSystem;
namespaceNiwalkerDemo
{
publicclassLogbook
{
publicstaticvoidLog(stringlogData)
{
Console.WriteLine("log:{0}",logData);
}
}
}
//Order.cs
usingSystem;
namespaceNiwalkerDemo
{
publicclassOrder
{
privateintorderId;
privatestringproduct;
privateintquantity;
publicOrder(intorderId)
{
this.orderId=orderId;
}
publicvoidSubmit()
{
Inventoryinventory=newInventory();//创立库存工具
//反省库存
if(inventory.Checkout(product,quantity))
{
Logbook.Log("Order"+orderId+"available");
inventory.Update(product,quantity);
}
else
{
Logbook.Log("Order"+orderId+"unavailable");
SendEmail();
}
}
publicstringProductName
{
get{returnproduct;}
set{product=value;}
}
publicintOrderId
{
get{returnorderId;}
}
publicintQuantity
{
get{returnquantity;}
set{quantity=value;}
}
publicvoidSendEmail()
{
Console.WriteLine("Sendemailtomanager");
}
}
}
上面是挪用程序:
//AppMain.cs
usingSystem;
namespaceNiwalkerDemo
{
publicclassAppMain
{
staticvoidMain()
{
Orderorder1=newOrder(100);
order1.ProductName="Item1";
order1.Quantity=150;
order1.Submit();
Orderorder2=newOrder(101);
order2.ProductName="Item2";
order2.Quantity=150;
order2.Submit();
}
}
}
程序看上往还不错,商务工具封装了商务划定规矩,运转的了局也切合请求。可是我仿佛听到你在埋怨了,没有吗?当你的客户的需求改动的时分(客户老是常常改动他们的需求),好比库存反省的划定规矩不是单一的反省产物的数目,还要反省产物是不是被预订的多种情形,那末你必要改动Inventory的代码,同时还要修正Order中的代码,我们的例子只是一个复杂的商务逻辑,实践的情形比这个要庞大的多。成绩在于Order工具同其他的工具之间是紧耦合的,从OOP的概念动身,如许的计划是有成绩的,假如你写出如许的程序,最少不会在我的团队内里被Pass.
你说了:“Noproblem!我们能够把商务逻辑抽出来放到一个专门计划的用来处置事件的工具中。”嗯,好主张,假如你是这么想的,也许我还能够给你一个发起,利用ObserverDesignPattern(察看者计划形式):你可使用delegate,在Order工具中界说一个BeforeSubmit和AfterSubmit事务,然后创立一个工具链表,将相干的工具拔出到这个链表中,如许就能够完成对Order提交事务的拦阻,在Order提交之前和提交以后主动举行需要的事件处置。假如你感乐趣的话,你能够本人下手来编写如许的一个代码,也许还要思索在散布式情况中(Order和Inventory不在一个中央)怎样处置工具之间的交互成绩。
侥幸的是,.NETFramework中供应了完成这类手艺的撑持。在.NETFramework中的工具Remoting和组件服务中,有一个主要的拦阻机制,在工具Remoting中,分歧的使用程序之间的工具的交互必要穿越他们的域界限,每个使用域也能够细分为多个Context(高低文情况),每个使用域也最少有一个默许的Context,即便在统一个使用域,也存在穿越分歧Context的成绩。NET的组件服务开展了COM+的组件服务,它利用ContextAttribute来完成象COM+一样的拦阻功效。经由过程对换用工具的拦阻,我们能够对一个办法的挪用举行前处置和后处置,同时也办理了上述的超过界限的成绩。
必要提示你,假如你在MSDN文档查ContextAttribute,我能够包管你得不就任何有助于懂得ContextAttribute的材料,你看到的将是这么一句话:“Thistypesupportsthe.NETFrameworkinfrastructureandisnotintendedtobeuseddirectlyfromyourcode.”——“本范例撑持.NETFramework基本布局,它不盘算间接用于你的代码。”不外,在msdn站点,你能够看到一些有关这方面的材料(见文章前面的参考链接)。
上面我们先容有关的几个类和一些观点,起首是:
ContextAttribute类
ContextAttribute派生自Attribute,同时它还完成了IContextAttribute和IContextProperty接口。一切自界说的ContextAttribute必需从这个类派生。
机关器:
ContextAttribute:机关器带有一个参数,用来设置ContextAttribute的称号。
大众属性:
Name:只读属性。前往ContextAttribute的称号
大众办法:
GetPropertiesForNewContext:假造办法。向新的Context增加属性汇合。
IsContextOK:假造办法。查询客户Context中是不是存在指定的属性。
IsNewContextOK:假造办法。默许前往true。一个工具大概存在多个Context,利用这个办法来反省新的Context中属性是不是存在抵触。
Freeze:假造办法。该办法用来定位被创立的Context的最初地位。
ContextBoundObject类
完成被拦阻的类,必要从ContextBoundObject类派生,这个类的工具经由过程Attribute来指定它地点Context,但凡进进该Context的挪用都能够被拦阻。该类从MarshalByRefObject派生。
以下是触及到的接口:
IMessage:界说了被传送的动静的完成。一个动静必需完成这个接口。
IMessageSink:界说了动静吸收器的接口,一个动静吸收器必需完成这个接口。
另有几个接口,我们将鄙人一节分离拦阻构架的完成道理中举行先容。捆绑编译器。用户不需要受制于厂家,自己就能将程序在新平台上编译运行。除了牛B轰轰的linux,估计也没有系统捆绑c/c++的编译器,而且许多新平台都无法支持复杂的c/c++编译器在上面直接运行。 |
|