朱祁林       zhuqilin   

WCF+WF双剑合璧构建微软的SOA系列(一):从一个简单的Demo开始

     本系列文章将从实例出发,以实例结尾。由浅入深讲解在我们项目中如何使用WCF和WF。我们会发现使用WCF+WF将造就出其他技术无法达到的高度。最后我会将程序架到云端。

     微软.net的3W(WPF、WCF、WF)战略如下图。WCF负责通信,WPF负责界面展示,WF负责处理业务逻辑,如下图。

untitled
     本系列文章会主要用到上图中的所有技术,但是主要讲述如何使用WCF和WF来实现系统的中间层。看过亮剑的朋友知道李云龙常打胜仗,并不是他懂得很多很多的战争的理论知识,而是来自实战中的经验。所以本系列的文章以实战为核心,在实战中出理论,不循规蹈矩,我将把自己的实力拿出来,亮出自己的宝剑。

    本系列文章除了WCF和WF两种主要的技术,还会用到很多其他的技术,WCF和WF两种技术将一用到底,也会牵扯到其它的技术如WPF、Asp.net MVC、Asp.net Web Form,NH、EF以及一些常用的技巧。我将在实战中进行演练和对比,在实战中发现最适合的技术。
     好了,牛皮吹完了,进入今天的正题。本文是这个系列的第一篇文章,我想了想还是从一个简单的Demo开始。通过这个实例来说明在项目中如何使用WCF和WF。WCF是如何进行数据传递的,WF是如何处理业务逻辑的。而实例的业务场景是非常常见的入库单:录入入库材料,更新库存数量。

系统架构

     首先,我将说说这个系统架构。可以分为4层。
     第一层:数据持久层:这个例子中我用EF实现的。
     第二层:业务逻辑层:很明显,这一层我要使用WF实现。
     第三层:服务层:很明显,这一层我要使用WCF实现。
     第四层:界面层:这里我使用Asp.net MVC。后续文章中,我将会陆续使用MVC、WebForm、WPF、SL四种界面进行展示。
     架构图如下:

architecture

数据库结构图:只有两种表。EnterStock表示入库记录表,Stock表示库存表。

db

数据持久层设计:前面提到了,我使用了EF4实现数据库的访问。EF的基本使用大家可以到网上查阅,这里我主要讲一下值得讲解的东西。由于使用EF生成Model,那么如何在MVC中进行DataAnnotation验证。看下面代码设计就明白了。以库存表为例:

public partial class StockAutoMetadata
{
        
    [DisplayName("Material ID")]
    [Required]
    public System.Guid MaterialID { get; set; }
        
    [DisplayName("Material Name")]
    [Required]
    [StringLength(50)]
    public string MaterialName { get; set; }
        
    [DisplayName("Quantity")]
    [Required]
    public int Quantity { get; set; }
}

 

 

 

[MetadataType(typeof(StockAutoMetadata))]
public partial class Stock
{
}
在partial类中注入元数据属性。
业务逻辑层设计:
用WF处理业务逻辑层是本系列文章的重点。我以入库操作为例。
1、增加材料的功能函数设计
public sealed class InsertEnterStock : CodeActivity
{
    public InArgument<EnterStock> Stock { get; set; }

    protected override void Execute(CodeActivityContext context)
    {
        InvoicingEntities entity = new InvoicingEntities();
        entity.AddToEnterStock(Stock.Get(context));
        entity.SaveChanges();
    }
}

2、更新库存的功能函数设计
public sealed class UpdateStock : CodeActivity
{
    public InArgument<EnterStock> EnterStock { get; set; }

    protected override void Execute(CodeActivityContext context)
    {
        InvoicingEntities entity = new InvoicingEntities();
        var res = (from r in entity.Stock.ToList() where r.MaterialID == EnterStock.Get(context).MaterialNO select r).FirstOrDefault();
        res.Quantity = res.Quantity + EnterStock.Get(context).Quantity;
        entity.ApplyCurrentValues(res.EntityKey.EntitySetName, res);
        entity.SaveChanges();
    }
}

3、入库操作的业务函数设计
rk 
分析:这里我将业务逻辑处理分成了两种形式。
1、功能函数:任务单一、简单;以代码的方式展现。
2、业务函数:业务复杂,有功能函数组合而成;以图形化的方式展现。
这样设计,我业务逻辑处理就非常清晰了。
服务层设计:在WCF中我要做的只是启动这些业务流程。
契约:
[ServiceContract]
public interface IInvoicingService
{

    [OperationContract]
    string EnterStock(EnterStock stock);

    [OperationContract]
    IEnumerable<Stock> GetStockList();

    [OperationContract]
    IEnumerable<EnterStock> GetEnterStockList();
    
}

实现:

public class InvoicingService : IInvoicingService
{

    public string EnterStock(EnterStock stock)
    {
        var p = new Dictionary<string, object> ();
        p.Add("argEnterStock", stock);
        WorkflowInvoker.Invoke(new EnterStockBusiness(), p);
        return "ok";

    }


    public IEnumerable<Stock> GetStockList()
    {
       IDictionary<string, object> outArgument = WorkflowInvoker.Invoke(new GetStockList());
       return outArgument["StockList"] as List<Stock>;
    }


    public IEnumerable<EnterStock> GetEnterStockList()
    {
        IDictionary<string, object> outArgument = WorkflowInvoker.Invoke(new  GetEnterStockList());
        return outArgument["EnterStockList"] as List<EnterStock>;
    }
}

在服务层中,我没有任何的业务逻辑判断和处理,我完全封装到业务逻辑层了。

界面层:界面层你可以使用如何你熟悉的技术去实现。这里我使用了Asp.net MVC。具体的实现我不细说了,就让我演示一下这个简单的Demo。

   1、简单的主页

1

   2、 库存中两种材料的库存数量都是0

2

   3、添加材料

3

4、库存数量被更新

4

5、入库记录列表

5

总结:本文是WCF+WF双剑合璧系列的第一篇文章,带领大家实现了一个简单的Demo。这个Demo还是原型,存在很多不足。希望大家能提出你宝贵的建议,帮助我写好这个系列的文章。下篇文章中将会谈谈系统如何实现错误处理机制。

代码:http://files.cnblogs.com/zhuqil/Invoicing.rar

作者:朱祁林
出处:http://zhuqil.cnblogs.com
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

 



posted @ 2010-11-01 00:51 麒麟 阅读(3654) 评论(19) 编辑 收藏

 回复 引用 查看   
#1楼2010-11-01 09:22 | 海家      
好呀,强烈关注,楼主加油
 回复 引用 查看   
#2楼2010-11-01 09:30 | Jeffrey.Liang      
已收藏,关注中。。。兄弟,顶你!
 回复 引用 查看   
#3楼2010-11-01 09:37 | 圣殿骑士      
呵呵,目前还没有看到SOA的影子!
 回复 引用 查看   
#4楼[楼主]2010-11-01 09:45 | 麒麟      
引用圣殿骑士:呵呵,目前还没有看到SOA的影子!

是啊,SOA是我写完了想到的。后续加进入!

 回复 引用 查看   
#5楼2010-11-01 09:52 | 圣殿骑士      
引用麒麟:
引用圣殿骑士:呵呵,目前还没有看到SOA的影子!

是啊,SOA是我写完了想到的。后续加进入!

恩,整篇文章仔细看了,写得很不错!加油!不过如果要用WCF+WF搭建SOA的话,做的工作比较多,自己要定义SOA Schema、实现发布订阅模式、实现消息传输、解析、监控机制等;如果用Biztalk的话就简单多了!

 回复 引用 查看   
#6楼2010-11-01 10:14 | 殇之舞      
其实我很想知道你说的EF是什么?
 回复 引用 查看   
#7楼[楼主]2010-11-01 10:30 | 麒麟      
引用殇之舞:其实我很想知道你说的EF是什么?

Entity Framework!

 回复 引用 查看   
#8楼2010-11-01 10:50 | 风雨者2      
强烈关注!

 回复 引用 查看   
#9楼[楼主]2010-11-01 13:17 | 麒麟      
引用风雨者2:强烈关注!

谢谢!:)

 回复 引用 查看   
#10楼2010-11-02 10:20 | jakie.hu      
支持!
 回复 引用 查看   
#11楼2010-11-02 10:49 | 狗尾草.      
关注,后期可能要跟进一个windows客户端项目,正考虑WCF和EF结合,一起学习了。
 回复 引用 查看   
#12楼2010-11-05 12:45 | 到了,明天      
期待更新..關注中
 回复 引用 查看   
#13楼2010-11-18 14:55 | 天水无声      
我想问一下,在wf实现业务逻辑层的过程中,一般的做法需要用到事物,包括添加入库记录和更新库存数量需要同步完成,这个里面可以实现这个吗??不能够知完成了一半,剩下的报错
 回复 引用 查看   
#14楼[楼主]2010-11-18 14:58 | 麒麟      
引用天水无声: 我想问一下,在wf实现业务逻辑层的过程中,一般的做法需要用到事物,包括添加入库记录和更新库存数量需要同步完成,这个里面可以实现这个吗??不能够知完成了一半,剩下的报错

WF里面有内置的事务处理。这个Demo中也用了事务处理的。
我好久没更新博客了。

 回复 引用 查看   
#15楼2011-01-04 17:37 | 会长      
我去,楼主,涉及范围太广泛了,不得不关注,谢谢楼主分享。
 回复 引用 查看   
#16楼2011-01-19 22:01 | john23.net      
不得不顶
 回复 引用 查看   
#17楼2011-03-26 00:21 | rhs      
多谢博主,看了你代码,有一处不明白,请你多多指点。在WCF中你真是直接调用逻辑层中WF的Activity,而非调用EnterStockBusiness.xaml整个工作流。如: WorkflowInvoker.Invoke(new EnterStockBusiness(), p);
这是什么呢?

 回复 引用 查看   
#18楼2011-04-13 15:33 | bloods      
不错! 不错! 博主什么时候继续更新呢?
 回复 引用 查看   
#19楼2011-10-25 12:49 | RockyXiang      

这个是什么问题?