音乐网站怎么做无线增值业务,西安网站建设方案优化,品牌建设情况介绍,dw网站轮播效果怎么做我们在开篇中提到#xff0c;希望能有一种办法#xff0c;能自动适应系统的环境配置#xff0c;在局域网小型应用中将直接访问数据库以获得最高的性能#xff0c;在分布式环境中自动使用WCF来获得较好的安全性和连通性。 但是#xff0c;我们不希望这样的特性使我们的开发…我们在开篇中提到希望能有一种办法能自动适应系统的环境配置在局域网小型应用中将直接访问数据库以获得最高的性能在分布式环境中自动使用WCF来获得较好的安全性和连通性。 但是我们不希望这样的特性使我们的开发变得过于复杂需要在新特性和工作量之间寻求一个合理的平衡点。 原理分析 用自动代理的业务层结构如下 检测到局域网配置时的情况将直接返回业务对象实例。 分布式配置的调用情况。 我们可以从图上看出使用局域网配置或分布式配置完全取决于自动代理对象而对于使用者表现层是完全透明的。当然对于分布式配置的情况传入业务端的参数和结果都是需要经过序列化的否则将无法在WCF中传输这是我们在开发业务层时需要注意的问题。 自动代理的对象实现很简单我们需要做的就是拦截调用将调用的信息业务对象名方法名参数等构建为WCF服务对象的参数通过统一的服务接口调用服务端服务端得到调用后根据调用信息实例化合适的业务对象调用相应的方法完成后将结果以统一的返回格式返回给自动代理对象而这些返回的数据将被反序列化后作为该方法的返回值。 代码实现 在目前的开源框架中Castle和Spring.net都提供了很好的自动代理的类库。我们将以Spring.net为例来实现自动代理对象。 public static class BizAutoWcfProxy
{public static T GetT(T instance) where T : class{var p new ProxyFactory(instance);p.AddAdvice(new AroundAdvise());return p.GetProxy() as T;}internal static IWcfProxy GetMethodProxy(){var service PubFunc.GetAppSetting(WcfService);if (string.IsNullOrEmpty(service)){return new WcfProxy();}var binding new NetTcpBinding(SecurityMode.None, false);var f new ChannelFactoryIWcfProxy(binding, service);var proxy f.CreateChannel();return proxy;}
} 上面是自动代理工厂的实现.这个工厂中提供了一个供自动代理对象使用的方法GetMethodProxy这个方法中检测应用程序配置文件的WcfService配置,如果配置不为空,则创建自动代理对象,否则直接返回. public class AroundAdvise : IMethodInterceptor
{public object Invoke(IMethodInvocation invocation){Log.Get().Debug(方法{0}被调用被拦截, invocation.Method.Name);try{var p BizAutoWcfProxy.GetMethodProxy();//调用信息var m new MethodProxy{ClassName invocation.TargetType.AssemblyQualifiedName, //业务对象名MethodName invocation.Method.Name //方法};//将调用参数也包含在调用信息中if (invocation.Arguments ! null invocation.Arguments.Length 0)m.Params invocation.Arguments.ToList().ConvertAll(PubFunc.Serialize.ObjToBytes).ToArray();//调用WCF服务var r p.Execute(m);//正常的情况,没有异常出现if (!r.HasException){//返回值object returnValue r.GetValue();var ind 0;//处理ref和out的参数的返回invocation.Method.GetParameters().ToList().ForEach(mp {if (mp.IsOut){invocation.Arguments[mp.Position] PubFunc.Serialize.BytesToObj(r.OutValue[ind]);}});return returnValue;}//出现异常的情况,反序列号异常信息,重新在客户端抛出var ex PubFunc.Serialize.BytesToObj(r.Exception) as Exception;if (ex ! null) throw ex;throw new Exception(无法反序列化异常信息);}catch (CommunicationException oe){Log.Get().Debug(WCF通讯错误, oe);throw;}}
} 上面是方法拦截的实现。这里除了需要考虑正常情况下调用之外还要考虑服务器端可能发生的异常这里增加了对异常的处理。 //唯一的WCF接口
[ServiceContract]
public interface IWcfProxy
{[OperationContract]ReturnValue Execute(MethodProxy m);
}
//服务实现
public class WcfProxy : IWcfProxy
{public ReturnValue Execute(MethodProxy m){try{//服务端实例化业务对象var con Type.GetType(m.ClassName).GetConstructor(BindingFlags.NonPublic| BindingFlags.Public| BindingFlags.Instance,null,new Type[0],null);var cls con.Invoke(new object[0]);//处理参数的反序列化var method cls.GetType().GetMethod(m.MethodName, BindingFlags.Instance | BindingFlags.Public);var pm new object[0];if (m.Params ! null m.Params.Length 0)pm m.Params.ToList().ConvertAll(PubFunc.Serialize.BytesToObj).ToArray();//调用var rlt method.Invoke(cls, pm);var r new ReturnValue();r.SetValue(rlt);//处理out参数var outPlist new Listbyte[]();method.GetParameters().ToList().ForEach(p {if(p.IsOut){outPlist.Add(PubFunc.Serialize.ObjToBytes(pm[p.Position]));}});if (outPlist.Count 0)r.OutValue outPlist.ToArray();//正常返回return r;}catch(TargetInvocationException ex1){var ex ex1.InnerException;//处理服务器端发生的两种异常信息,这些属于正常的业务异常,需要返回到客户端if (ex is BizException || ex is DAException){var r new ReturnValue();r.HasException true;r.Exception PubFunc.Serialize.ObjToBytes(ex);return r;}else{//非正常情况下的异常,统一包装为服务端异常返回var serverex new ServerException(ex.Message);serverex.Trace ex.StackTrace;var r new ReturnValue();r.HasException true;r.Exception PubFunc.Serialize.ObjToBytes(serverex);return r;}}}
}
//服务返回对象
[DataContract]
public class ReturnValue
{[DataMember]public bool HasException { get; set; }[DataMember]public byte[] Exception { get; set; }[DataMember]public byte[] Value { get; set; }[DataMember]public byte[][] OutValue { get; set; }public void SetValue(object value){if (value null){Value null; return;}ValuePubFunc.Serialize.ObjToBytes(value);}public object GetValue(){if (Value null){return null;}return PubFunc.Serialize.BytesToObj(Value);}
}
//调用信息
[DataContract]
public class MethodProxy
{[DataMember]public string ClassName { get; set; }[DataMember]public string MethodName { get; set; }[DataMember]public byte[][] Params{get;set;}
} 这里是完整的服务端的方法提供WCF接口处理业务层对象调用的过程。 实现不算复杂代码也不多欢迎讨论。不足之处请指正。转载于:https://www.cnblogs.com/yiway/archive/2011/01/24/MY_FW_4.html