• [转]Spring.NET企业架构实践之 NHibernate + Spring.NET + WCF + Windows服务 + Silverlight 中小企业应用架构完整Demo


    一、概括

      此Demo使用的开发工具是:VS2010,数据库任意,Silvelright版本是4.0。

    Demo分为三层(Tier),数据库,服务器端,客户端。其中,服务器端又分为三层(Layer),持久层,服务层,门面层。

    WCF以Windows服务作为宿主,客户端使用Silverlight运行浏览器之外。

    图1

      图1是解决方案中包含的项目。其中,Server文件夹下是服务器端的代码,Host文件夹下是服务器端的Windows服务宿主,Client文件夹下是Silverlight应用程序。

      二、技术点

      WCF的Binding配置使用NetTcpBinding,是为了实现“回调”。

      其中,服务器端中,添加,修改,删除数据时调用客户端的回调:

    Callback
    private void ReceiveProduct(Product entity)
            {
                
    try
                {
                    Parallel.ForEach(callBackList, (item) 
    =>
                    {
                        
    try
                        {
                            item.ReceiveProduct(entity);
                        }
                        
    catch (Exception ex)
                        {
                            System.Console.WriteLine(ex.ToString());
                        }
                    });
                }
                
    catch (Exception ex)
                {
                    System.Console.WriteLine(ex.ToString());
                }
            }


    public void DeleteProduct(Guid id)
            {
                var entity 
    = this.ProductManager.Get(id);
                
    if (entity == null)
                {
                    
    return;
                }

                
    this.ProductManager.Delete(entity);

                
    try
                {
                    Parallel.ForEach(callBackList, (item) 
    =>
                    {
                        
    try
                        {
                            item.ClearProduct(id);
                        }
                        
    catch (Exception ex)
                        {
                            System.Console.WriteLine(ex.ToString());
                        }
                    });
                }
                
    catch (Exception ex)
                {
                    System.Console.WriteLine(ex.ToString());
                }
            }

      客户端收到回调时处理该请求:

    Client
    public void Proxy_ReceiveProductReceived(object sender, ReceiveProductReceivedEventArgs e)
            {
                var list 
    = this.grid.ItemsSource as ObservableCollection<Product>;
                
    if (list == null)
                {
                    
    return;
                }

                var entity 
    = list.FirstOrDefault(f => f.ID == e.entity.ID);
                
    if (entity == null)
                {
                    list.Add(e.entity);
                }
                
    else
                {
                    entity.Code 
    = e.entity.Code;
                    entity.Name 
    = e.entity.Name;
                    entity.BuyPrice 
    = e.entity.BuyPrice;
                    entity.SellPrice 
    = e.entity.SellPrice;
                    entity.QuantityPerUnit 
    = e.entity.QuantityPerUnit;
                    entity.Remark 
    = e.entity.Remark;
                    entity.Unit 
    = e.entity.Unit;
                }
            }

    public void Proxy_ClearProductReceived(object sender, ClearProductReceivedEventArgs e)
            {
                var list 
    = this.grid.ItemsSource as ObservableCollection<Product>;
                
    if (list == null)
                {
                    
    return;
                }

                var entity 
    = list.FirstOrDefault(f => f.ID == e.id);
                
    if (entity == null)
                {
                    
    return;
                }

                list.Remove(entity);
            }

      

      这样多个客户端的数据就保持一致了。

      由于目前Spring.NETOpenSessionInView仅适用于Web,所以我使用AOP拦截WCF的Contract接口实现类,在调用前打开SessionScope,调用后关闭SessionScope。这样在同一请求中就实现了NHibernateSession同步。

    OpenSessionInViewModule
    public class OpenSessionInViewModule : IMethodInterceptor
        {
            
    private static log4net.ILog logger = log4net.LogManager.GetLogger(typeof(OpenSessionInViewModule));

            
    public object Invoke(IMethodInvocation invocation)
            {
                SessionScope sessionScope 
    = new SessionScope("appSettings"typeof(SessionScope), false);
                
    try
                {
                    sessionScope.Open();
                    
    object obj = invocation.Proceed();
                    
    return obj;
                }
                
    catch (Exception ex)
                {
                    System.Console.WriteLine(ex.ToString());
                    logger.Error(ex);
                    
    return null;
                }
                
    finally
                {
                    sessionScope.Close();
                }
            }
        }

      Windows服务的部署。

      Host文件夹下有两个批处理(.bat)文件:Install.bat和UnInstall.bat。分别为安装和卸载Windows服务的命令。如图2.1所示。

    图2.1

      Silverlight 4的跨越需要在http服务器的80端口放置clientaccesspolicy.xml的跨域文件,如图2.2所示。

    图2.2

    这里的http服务器可以不为IIS,但是输入域名+clientaccesspolicy.xml的时候必须能够访问到clientaccesspolicy.xml页面。

    clientaccesspolicy.xml
    <?xml version="1.0" encoding="utf-8"?>
    <access-policy>
      
    <cross-domain-access>
        
    <policy>
          
    <allow-from http-request-headers="*">
            
    <domain uri="*" />
          
    </allow-from>
          
    <grant-to>
            
    <socket-resource port="4502-4534" protocol="tcp" />
            
    <resource path="/" include-subpaths="true"/>
          
    </grant-to>
        
    </policy>
      
    </cross-domain-access>
    </access-policy>

      三,运行效果

      

      图3.1

      图3.1是NHibernate自动表后的数据库。

      

    图3.2

      图3.2是Silverlight应用程序的运行效果。

       运行多个客户端的效果,如图3.3所示。

      

    图3.3

      点击添加或者修改按钮,弹出修改页面(如图3.4所示)。然后点击确定按钮保持数据,由于是双向通行,则两个客户端的数据保持一致(如图3.5所示)。

    图3.4

    图3.5

      四、总结

      该Demo是一个Spring.NETNHibernate框架的综合应用,实用于小型项目的企业应用。此架构有较强的实用性,并在项目开发中达到“快速开发”的目的。希望爱好钻研的朋友能够下载我的代码,并我和一起讨论。

      代码下载

      出处:http://www.cnblogs.com/GoodHelper/archive/2010/10/16/SpringNetFramework_Step2.html

      欢迎转载,但需保留版权。

  • 相关阅读:
    MyBatis学习总结(八)——Mybatis3.x与Spring4.x整合
    MyBatis学习总结(五)——实现关联表查询
    MyBatis学习总结(六)——调用存储过程
    MyBatis学习总结(四)——解决字段名与实体类属性名不相同的冲突
    MyBatis学习总结(二)----使用MyBatis对表执行CRUD操作
    MyBatis学习总结(三)——优化MyBatis配置文件中的配置
    CORS跨域问题
    按指定后缀名删除文件的demo
    Markdown起步
    Linux和git起步
  • 原文地址:https://www.cnblogs.com/Leo_wl/p/1853192.html
Copyright © 2020-2023  润新知