public OrderInfo Receive(int timeout) { base.timeout = TimeSpan.FromSeconds(Convert.ToDouble(timeout)); return Receive(); }
public void Send(OrderInfo orderMessage) { // This method does not involve in distributed transaction and optimizes performance using Single type base.transactionType = MessageQueueTransactionType.Single; base.Send(orderMessage); }所以,最后的类图应该如下: 注意在Order类的Receive()方法中,是用new关键字而不是override关键字来重写其父类PetShopQueue的Receive()虚方法。因此,如果是实例化如下的对象,将会调用PetShopQueue的Receive()方法,而不是子类Order的Receive()方法:PetShopQueue queue = new Order();queue.Receive();从设计上来看,由于PetShop采用“面向接口设计”的原则,如果我们要创建Order对象,应该采用如下的方式:IOrder order = new Order();order.Receive();考虑到IOrder的实现有可能的变化,PetShop仍然利用了工厂模式,将IOrder对象的创建用专门的工厂模块进行了封装: 在类QueueAccess中,通过CreateOrder()方法利用反射技术创建正确的IOrder类型对象: public static PetShop.IMessaging.IOrder CreateOrder() { string className = path + ".Order"; return PetShop.IMessaging.IOrder)Assembly.Load(path).CreateInstance(className); }path的值通过配置文件获取:private static readonly string path = ConfigurationManager.AppSettings["OrderMessaging"];而配置文件中,OrderMessaging的值设置如下:
Order order = new Order(); while (true) { // queue timeout variables TimeSpan datetimeStarting = new TimeSpan(DateTime.Now.Ticks); double elapsedTime = 0;
int processedItems = 0;
ArrayList queueOrders = new ArrayList();
using (TransactionScope ts = new TransactionScope(TransactionScopeOption.Required, tsTimeout)) { // Receive the orders from the queue for (int j = 0; j < batchSize; j++) { try { //only receive more queued orders if there is enough time if ((elapsedTime + queueTimeout + transactionTimeout) < tsTimeout.TotalSeconds) { queueOrders.Add(order.ReceiveFromQueue(queueTimeout)); } else { j = batchSize; // exit loop }
//update elapsed time elapsedTime = new TimeSpan(DateTime.Now.Ticks).TotalSeconds - datetimeStarting.TotalSeconds; } catch (TimeoutException) { //exit loop because no more messages are waiting j = batchSize; } } //process the queued orders for (int k = 0; k < queueOrders.Count; k++) { order.Insert((OrderInfo)queueOrders[k]); processedItems++; totalOrdersProcessed++; }
//batch complete or MSMQ receive timed out ts.Complete(); }
Console.WriteLine("(Thread Id " + Thread.CurrentThread.ManagedThreadId + ") batch finished, " + processedItems + " items, in " + elapsedTime.ToString() + " seconds."); } }首先,它会通过PetShop.BLL.Order类的公共方法ReceiveFromQueue()来获取消息队列中的订单数据,并将其放入到一个ArrayList对象中,然而再调用PetShop.BLL.Order类的Insert方法将其插入到Order和Inventory数据库中。在PetShop.BLL.Order类中,并不是直接执行插入订单的操作,而是调用了IOrderStrategy接口的Insert()方法:public void Insert(OrderInfo order) { // Call credit card procesor ProcessCreditCard(order);
// Insert the order (a)synchrounously based on configuration orderInsertStrategy.Insert(order);}在这里,运用了一个策略模式,类图如下所示: 在PetShop.BLL.Order类中,仍然利用配置文件来动态创建IOrderStategy对象:private static readonly PetShop.IBLLStrategy.IOrderStrategy orderInsertStrategy = LoadInsertStrategy();private static PetShop.IBLLStrategy.IOrderStrategy LoadInsertStrategy() { // Look up which strategy to use from config file string path = ConfigurationManager.AppSettings["OrderStrategyAssembly"]; string className = ConfigurationManager.AppSettings["OrderStrategyClass"];
// Using the evidence given in the config file load the appropriate assembly and class return (PetShop.IBLLStrategy.IOrderStrategy)Assembly.Load(path).CreateInstance(className);}由于OrderProcessor是一个单独的应用程序,因此它使用的配置文件与PetShop不同,是存放在应用程序的App.config文件中,在该文件中,对IOrderStategy的配置为:
没有评论:
发表评论