• [转载]我的基于WCF的SOA架构项目实战


    http://www.cnblogs.com/datacool/archive/2011/07/13/wcfsoa.html

    本人才疏学浅,在现在的项目中即是程序员又是架构设计组组长。在使用WCF技术前看了无数号称WCF实战博客,没有一篇是我想要的。不过也算学到些皮毛。在此谢过,对你们的善意分享和辛勤劳动表示万分的感谢。由于以前是在csdn写博客,到博客园发文算是第一次。还请各位高手跳过,但愿不会浪费各位的表情。这里先上几张图,后面再讲过程。

    • 解决方案截图

    架构过程遇到的问题和解决方法。

    1、要不要使用dto对象,要不要建立DTO层?

    解决办法是巧妙的将实体对象和dto对象合并,这样少了转换的过程。感觉还行。

    样本如下:

    namespace RTLS.Entities
    {
        [Serializable, DataContract(IsReference = true)]
        [KnownType(typeof(SysRolefunc))]
        public class SysRole
        {
            [DataMember]
            public virtual int Roleid { get; set; }
            [DataMember]
            public virtual string Rolename { get; set; }
            [DataMember]
            public virtual bool Active { get; set; }
            [DataMember]
            public virtual string Desc { get; set; }
            [DataMember]
            public virtual DateTime? Timestamp { get; set; }
            [DataMember]
            public virtual string Remark { get; set; }

            private IList<SysRolefunc> list;

            //一对多关系:角色(Role)有一个或多个角色功能(SysRolefunc)
            [DataMember]
            public virtual IList<SysRolefunc> RoleFuncs
            {
                get
                {
                    if (list == null)
                    {
                        list = new List<SysRolefunc>();
                    }
                    return list;
                }
                set
                {
                    list = value;
                }
            }       
        }
    }

    using System;
    using System.ServiceModel;
    namespace RTLS.IServices
    {
        [ServiceContract]
        public interface ISysRoleService
        {
            [OperationContract]
            bool AddSysRole(RTLS.Entities.SysRole role);
            [OperationContract]
            bool DeleteSysRole(RTLS.Entities.SysRole role);
            [OperationContract]
            System.Collections.Generic.IList<RTLS.Entities.SysRole> GetAll(bool isActive);
            [OperationContract]
            System.Collections.Generic.IList<RTLS.Entities.SysRole> GetPageResults(int curPageNo, int limit,
                                                                                   string name, bool isActive,
                                                                                   ref int totalCount);
            [OperationContract]
            System.Collections.Generic.IList<RTLS.Entities.SysRole> GetRoleByUserId(int userID);
            [OperationContract]
            bool ModifySysRole(RTLS.Entities.SysRole role);
        }
    }

    namespace RTLS.Services
    {
        /// <summary>
        /// 系统角色服务类
        /// </summary>
        public class SysRoleService : ISysRoleService
        {
            private SysRoleBiz biz = new SysRoleBiz();
            public bool AddSysRole(Entities.SysRole role)
            {
                var result = biz.AddSysRole(role);
                return result.Success();
            }

            public bool DeleteSysRole(Entities.SysRole role)
            {
                return biz.DeleteSysRole(role);
            }

            public IList<Entities.SysRole> GetAll(bool isActive)
            {
                return biz.GetAll(isActive);
            }

            public IList<Entities.SysRole> GetPageResults(int curPageNo, int limit, string name, bool isActive, ref int totalCount)
            {
                return biz.GetPageResults(curPageNo,limit,name,isActive,ref totalCount);
            }

            public IList<Entities.SysRole> GetRoleByUserId(int userID)
            {
                return biz.GetRoleByUserId(userID);
            }

            public bool ModifySysRole(Entities.SysRole role)
            {
                return biz.ModifySysRole(role);
            }
        }
    }

    虽然说不推荐这样用,但是工期有限啊。没有使用Linq,所以要真是dto-->entity,entity-->entity转换来转换去的要死人的。因为这个原因曾经打算放弃使用WCF,让客户端直接引用BLL和Model层。后来发现这样合并了之后可以继续下去了,就这样做了。对错先暂且不论。

    2、怎么调试和设置WCF参数?

    当然是摸索了,跌倒,跌倒...爬起来,再来!上几张图:

     <service behaviorConfiguration="RTLS.Services.ServiceBehavior"
          name="RTLS.Services.SystemFunctionService">
            <endpoint address="net.tcp://192.168.1.123:9998/RTLS_SysFun_Svr" binding="netTcpBinding" bindingConfiguration="myNetTcpBinding"
              name="net" contract="RTLS.IServices.ISystemFunctionService" />
            <endpoint address="mex" binding="mexTcpBinding" bindingConfiguration=""
              name="mex" contract="IMetadataExchange" />
            <host>
              <baseAddresses>
                <add baseAddress="net.tcp://192.168.1.123:9998/RTLS_SysFun_Svr" />
              </baseAddresses>
            </host>
          </service>
        </services>

    3.一个Winnt服务如何host多个wcf服务?

            protected override void OnStart(string[] args)
            {
                if (serviceHostes.Count > 0) serviceHostes.Clear();
                var configuration = ConfigurationManager.OpenExeConfiguration(Assembly.GetEntryAssembly().Location);
                ServiceModelSectionGroup serviceModelSectionGroup = (ServiceModelSectionGroup)configuration.GetSectionGroup("system.serviceModel");
                // 开启每个服务
                foreach (ServiceElement serviceElement in serviceModelSectionGroup.Services.Services)
                {               
                    var wcfServiceType = Assembly.Load("RTLS.Services").GetType(serviceElement.Name);
                    var serviceHost = new ServiceHost(wcfServiceType);              
                    serviceHostes.Add(serviceHost);
                    serviceHost.Opened += delegate
                    {
                        LogManager.WriteLog("Log", string.Format("{0}开始监听Uri为:{1}",
                        serviceElement.Name, serviceElement.Endpoints[0].Address.ToString()));
                    };
                    serviceHost.Open();               
                }           
            }

    这个办法是在吉日大哥的通用权限组件里面看到的,这里对吉日大哥表示衷心的感谢!希望大伙尊重一下扎扎实实搞技术的人,我不是为了跟吉日大哥打广告。做人要懂得感恩!你技术牛,你鄙视我可以,我不羡慕你,也不一定要屌你。

    4、怎样使用泛型工厂类来简化和重构代码?

    这个正在尝试中,毕竟先完成了。

    5、使用winnt服务的方式安装、发布容易吗?好用吗?

     /// <summary>
            /// 应用程序的主入口点。
            /// </summary>
            static void Main(string[] args)
            {
                if (args.Length > 0)
                {
                    AssemblyInstaller myAssemblyInstaller;
                    myAssemblyInstaller = new AssemblyInstaller();
                    myAssemblyInstaller.UseNewContext = true;
                    myAssemblyInstaller.Path = System.AppDomain.CurrentDomain.BaseDirectory + "\\" + System.AppDomain.CurrentDomain.FriendlyName;
                    System.Collections.Hashtable mySavedState = new System.Collections.Hashtable();
                    switch (args[0].ToLower())
                    {
                        case "-i":
                            myAssemblyInstaller.Install(mySavedState);
                            myAssemblyInstaller.Commit(mySavedState);
                            myAssemblyInstaller.Dispose();
                            return;
                        case "-u":
                            myAssemblyInstaller.CommandLine = new string[1] { "/u" };
                            myAssemblyInstaller.Uninstall(null);
                            myAssemblyInstaller.Dispose();
                            return;
                        default:
                            System.Console.WriteLine("------参数说明------");
                            System.Console.WriteLine("- i 安装服务!");
                            System.Console.WriteLine("- u 卸载服务!");
                            System.Console.ReadKey();
                            return;
                    }
                }

                ServiceBase[] ServicesToRun;
                ServicesToRun = new ServiceBase[]
                {
                    new RtlsHostSvr()
                };
                ServiceBase.Run(ServicesToRun);

                想知道怎样调试服务程序像调试控制台程序一样吗? 把服务的OnStart方法标记为public new .默认是protected override.然后像下面那样取消那些注释,并注释上面  的代码就ok了。
                //var sHostSvr = new RtlsHostSvr();
                //sHostSvr.OnStart(null);
                //System.Threading.Thread.Sleep(10000);
                //sHostSvr.OnStop();
            }

  • 相关阅读:
    并发容器-ConcurrentHashMap
    java中的volatile
    Java 8并发工具包简介
    jQuery ajax() 参数,回调函数,数据类型,发送数据到服务器,高级选项
    mint-ui vue双向绑定
    CSS完美兼容IE6/IE7/IE8/IE9/IE10的通用方法
    html中offsetTop、clientTop、scrollTop、offsetTop各属性介绍
    javascript组件的基本结构
    vue生命周期的介绍
    document.ready和onload的区别
  • 原文地址:https://www.cnblogs.com/fx2008/p/2241285.html
Copyright © 2020-2023  润新知