| 本人才疏学浅,在现在的项目中即是程序员又是架构设计组组长。在使用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(); } |