Niwalker (original) Attribute Attribute starts from this section we discussed the advanced application of Attribute, for this, I have an actual example: We have an order processing system, when a order is submitted, system check Library
Save, if the stock deposit satisfies the number of orders, the system records the order processing record, then updates the stock, if the stock stock is below the number of orders, the system makes the corresponding record while in stock
The administrator sends an email. For the convenience of demonstration, we have simplified the example:
//Inventory.csusing system; using system.collections;
Namespace niwalkerdemo {public class inventory {
Private hashtable inventory = new hashtable (); public inventile () {inventory ["item1"] = 100; inventory ["item2"] = 200;
public bool Checkout (string product, int quantity) {int qty = GetQuantity (product); return qty> = quantity;} public int GetQuantity (string product) {int qty = 0; if (! inventory [product] = null) qty = (int) Inventory [Product]; Return Qty;} PUBLIC VOID Update (String Product, INT Quantity) {INT Qty = getquantity (Product); Inventory [Product] = Qty-Quantity;}}}}}
//Logbook.cs concernsing system;
Namespace niwalterdemo {public class logbook {public static void log (string logdata) {console.writeline ("log: {0}", logdata;}}}
//Order.cs concernsing system;
namespace NiwalkerDemo {public class Order {private int orderId; private string product; private int quantity; public Order (int orderId) {this.orderId = orderId;} public void Submit () {Inventory inventory = new Inventory (); // Create Inventory object // Check inventory IF (Inventory.Checkout (Product, Quantity)) {logbook.log ("ORDER" ORDERID "Available"); Inventory.Update (Product, Quantity);} else {logbook.log ("ORDER " orderId " unavailable "); SendEmail ();}} public string ProductName {get {return product;} set {product = value;}} public int OrderId {get {return orderId;}} public int Quantity {get {return Quantity;}}} public void sendemail () {Console.writeline ("Send Email to Man Ager ");}}} The following is the calling program:
//Appmain.cs
Using system;
namespace NiwalkerDemo {public class AppMain {static void Main () {Order order1 = new Order (100); order1.ProductName = "Item1"; order1.Quantity = 150; order1.Submit (); Order order2 = new Order (101) ORDER2.PRODUCTNAME = "item2"; Order2.quantity = 150; Order2.Submit ();}}}
The program seems yet, and the business object encapsulates business rules, and the results of operation also meet the requirements. But I seem to hear you complaining, no? When your customer's needs change
(Customers always change their needs), such as inventory check rules are not a single check product, but also check if the product is booked, then you need to change
Inventory's code, but also modify the code in Order, our example is just a simple business logic, and the actual situation is more complicated than this. The problem is that the ORDER object is tight between the other objects, from OOP's point of view, such a design is problematic, if you write this program, at least you will not be passed in my team.
You said: "No Problem! We can draw business logic to a specially designed object to handle transactions." Well, good idea, if you think so, maybe I
You can also give you a proposal, using Observer Design Pattern: You can use Delegate, define a beforSubmit in the ORDER object and
AfTersubmit event, then create an object chain list, insert the relevant object into this list, so you can implement interception of Order Submit Event, before and in the order of ORDER
The necessary transaction will be automatically performed after payment. If you are interested, you can write your own code, perhaps considering in a distributed environment (ORDER and
Inventory is not in a place) how to handle the interaction between objects.
Fortunately, the .NET Framework provides support for this technology. There is an important interception mechanism in the object transing and component services in .NET Framework, there is an important interception mechanism.
In Remoting, the interaction between objects between different applications requires crossing their domain boundaries, each application domain can also be subdivided into multiple context, each should
There is at least one default Context, even in the same application domain, there is also a problem that crossing different context. NET's component service develops Com component service, it is used
Context Attribute is implemented as a COM . By interception of calling objects, we can perform pre-processing and post-processing on a method of calling, and also solve it.
Problem in the boundary.
Need to remind you if you check the ContextTattribute in the MSDN document, I can guarantee that you have to help understand the information of ContexttRibute, you will see this.
: "This Type supports the .NET Framework infrastructure and is not intended to be used Directly from your code." - "
Type supports the .NET Framework infrastructure, it is not intended to be used directly for your code. "However, in the MSDN site, you can see some information about this (see the back of the article)
Review link).
Let's introduce several classes and some concepts, first of all:
ContextAttribute class
ContextAttribute is derived from Attribute, and it also implements the icontextAttribute and IconTextProperty interface. All custom ContextaTRibuters must be from this
The class is derived. Constructor: ContextAttribute: The constructor has a parameter to set the name of ContextAttribute.
Public property: Name: Read-only properties. Returns the name of ContextAttribute
Public method: getPropertiesforneWContext: Virtual method. Add an attribute collection to the new Context. ISCONTEXTOK: Virtual Method. Query if there is a specified property in customer context. IsnewContextok: virtual method. Returns True by default. An object may exist multiple contexts, using this method to check if there is a conflict in the new context. Freeze: Virtual method. This method is used to locate the last position of the CONTEXT created. ContextBoundObject class
Implement the intercepted class, need to be derived from the ContextBoundObject class, this class object can specify its context through Attribute, and all the calls that enter the context can be
Interception. This class is derived from MarshalByrefObject.
The following is the interface involved:
IMessage: Defines the implementation of messages transmitted. A message must implement this interface.
IMESSAGESINK: Defines the interface of the message receiver, and a message receiver must implement this interface.
Reference article: decouple components by incjecting Custom Services INTO YOUR Object's Interception CHAIN