Extending WCF using IServiceBehavior, IOperationBehavior, and IParameterInspector
[ServiceContract(Name = "PasswordGenerator")]
public interface IPasswordGenerator
{
[OperationContract(Name = "GeneratePassword")]
string GeneratePassword();
[OperationContract(Name="ParameterizedPasswordGenerator")]
string GeneratePassword(int length);
} public class PasswordGenerator:IPasswordGenerator
{
[OperationBehavior()]
public string GeneratePassword()
{
return "You called GeneratePassword()";
} [OperationBehavior()]
public string GeneratePassword(int length)
{
return "You called GeneratePassword(int length) overload";
}
}
static void Main(string[] args)
{
ServiceEndpoint serviceEndpoint;
Uri basePipeAddress = new Uri(@"net.Pipe://localhost/Password/Mine");
using (ServiceHost host =
new ServiceHost(typeof(Password.PasswordGenerator), basePipeAddress))
{
serviceEndpoint = host.AddServiceEndpoint(typeof(
Password.IPasswordGenerator), new NetNamedPipeBinding(), string.Empty);
host.Open(); using (var factory = new
ChannelFactory<password.passwordgenerator>(new NetNamedPipeBinding()))
{
var proxy = factory.CreateChannel(serviceEndpoint.Address);
proxy.GeneratePassword();
proxy.GeneratePassword(1500);
factory.Close();
}
host.Close();
}
}
public static class Logger
{
private static void Log(string message)
{
try
{
using (var stream = new StreamWriter(@"G:\log.log", true))
{
stream.WriteLine(message); stream.Flush();
stream.Close();
}
}
catch (Exception)
{ }
}
public static void Log(string className, string methodName, string parameter)
{
Log(string.Format("Class {0} called method {1} with parameter {2} @ {3}",
className, methodName, parameter, DateTime.Now));
} }
First Extension
public class MyServiceBehaviorAttribute : Attribute, IServiceBehavior
{ public void AddBindingParameters(ServiceDescription serviceDescription,
ServiceHostBase serviceHostBase,
Collection<ServiceEndpoint> endpoints,
BindingParameterCollection bindingParameters)
{
Logger.Log("MyServiceBehaviorAttribute",
"AddBindingParameters", serviceDescription.Name);
}
public void ApplyDispatchBehavior(ServiceDescription serviceDescription,
ServiceHostBase serviceHostBase)
{
Logger.Log("MyServiceBehaviorAttribute",
"ApplyDispatchBehavior", serviceDescription.Name);
}
public void Validate(ServiceDescription serviceDescription,
ServiceHostBase serviceHostBase)
{
Logger.Log("MyServiceBehaviorAttribute",
"Validate", serviceDescription.Name);
}
}
Second Extension
public class MyOperationBehavior:Attribute, IOperationBehavior
{
public void AddBindingParameters(OperationDescription operationDescription,
System.ServiceModel.Channels.BindingParameterCollection bindingParameters)
{
Logger.Log("MyOperationBehavior",
"AddBindingParameters", operationDescription.Name);
} public void ApplyClientBehavior(OperationDescription operationDescription,
System.ServiceModel.Dispatcher.ClientOperation clientOperation)
{
clientOperation.ParameterInspectors.Add(new MyParameterInspector());
Logger.Log("MyOperationBehavior",
"ApplyClientBehavior", operationDescription.Name);
} public void ApplyDispatchBehavior(OperationDescription operationDescription,
System.ServiceModel.Dispatcher.DispatchOperation dispatchOperation)
{
dispatchOperation.ParameterInspectors.Add(new MyParameterInspector());
Logger.Log("MyOperationBehavior",
"ApplyDispatchBehavior", operationDescription.Name);
} public void Validate(OperationDescription operationDescription)
{
Logger.Log("MyOperationBehavior", "Validate", operationDescription.Name);
}
}
Third Extension
class MyParameterInspector:IParameterInspector
{
public void AfterCall(string operationName, object[] outputs,
object returnValue, object correlationState)
{
Logger.Log("MyParameterInspector", "AfterCall", operationName);
} public object BeforeCall(string operationName, object[] inputs)
{
Logger.Log("MyParameterInspector", "BeforeCall", operationName);
return null;
}
}
[__strong__][MyServiceBehaviorAttribute()]
public class PasswordGenerator:IPasswordGenerator
{
[OperationBehavior(),MyOperationBehavior]
public string GeneratePassword()
{
return "You called GeneratePassword()";
} [OperationBehavior()]
[MyOperationBehavior]
public string GeneratePassword(int length)
{
return "You called GeneratePassword(int length) overload";
}
---------------------------------------------------------------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Text;
using System.ServiceModel;
using System.ServiceModel.Description;
using System.ServiceModel.Dispatcher;
using System.Reflection; namespace AOPAndWCF
{
class MyParameterInspector: IOperationBehavior, IParameterInspector
{
#region IOperationBehavior Members
/// <summary>
///
/// </summary>
/// <param name="operationDescription"></param>
/// <param name="bindingParameters"></param>
public void AddBindingParameters(OperationDescription operationDescription, System.ServiceModel.Channels.BindingParameterCollection bindingParameters)
{ }
/// <summary>
///
/// </summary>
/// <param name="operationDescription"></param>
/// <param name="clientOperation"></param>
public void ApplyClientBehavior(OperationDescription operationDescription, ClientOperation clientOperation)
{ }
/// <summary>
///
/// </summary>
/// <param name="operationDescription"></param>
/// <param name="dispatchOperation"></param>
public void ApplyDispatchBehavior(OperationDescription operationDescription, DispatchOperation dispatchOperation)
{
dispatchOperation.ParameterInspectors.Add(this);
} /// <summary>
///
/// </summary>
/// <param name="operationDescription"></param>
public void Validate(OperationDescription operationDescription)
{ } #endregion /// <summary>
/// 调用方法后 输出结果值
/// </summary>
/// <param name="operationName"></param>
/// <param name="outputs"></param>
/// <param name="returnValue"></param>
/// <param name="correlationState"></param>
public void AfterCall(string operationName, object[] outputs, object returnValue, object correlationState)
{
Console.WriteLine("*************返回操作名称:" + operationName+"*************");
Console.WriteLine("*************返回操作编号:" + correlationState.ToString() + "**************");
for (int i = 0; i < outputs.Length; i++)
{ Type T = outputs[i].GetType();
Console.WriteLine("返回操作参数" + i.ToString() + " 类型为:" + T.ToString());
Console.WriteLine("返回操作参数" + i.ToString() + " ToString为:" + outputs[i].ToString());
Console.WriteLine("返回操作参数" + i.ToString() + " 属性:");
PropertyInfo[] PIs = T.GetProperties();
foreach (PropertyInfo PI in PIs)
{
Console.Write(PI.Name + ":");
Console.WriteLine(PI.GetValue(outputs[i], null));
} } Type Treturn = returnValue.GetType();
Console.WriteLine("操作返回值" + " 类型为:" + Treturn.ToString());
Console.WriteLine("操作返回值" + " ToString为:" + Treturn.ToString());
Console.WriteLine("操作返回值" + " 属性:"); if (Treturn.ToString() != "System.String")
{
PropertyInfo[] PIreturns = Treturn.GetProperties();
foreach (PropertyInfo PI in PIreturns)
{
Console.Write(PI.Name + ":");
Console.WriteLine(PI.GetValue(returnValue, null));
}
} }
/// <summary>
/// 调用方法前 输出参数值
/// </summary>
/// <param name="operationName"></param>
/// <param name="inputs"></param>
/// <returns></returns>
public object BeforeCall(string operationName, object[] inputs)
{
Guid guid = Guid.NewGuid(); Console.WriteLine("*************调用操作名称:" + operationName+"**************");
Console.WriteLine("*************调用操作编号:" + guid.ToString () + "**************");
for (int i = 0; i < inputs.Length ; i++)
{ Type T = inputs[i] .GetType ();
Console.WriteLine("操作参数"+i.ToString ()+" 类型为:"+T.ToString ());
Console.WriteLine("操作参数" + i.ToString() + " ToString为:" + inputs[i].ToString());
Console.WriteLine("操作参数" + i.ToString() + " 属性:");
PropertyInfo [] PIs = T.GetProperties();
foreach (PropertyInfo PI in PIs)
{
Console.Write ( PI.Name +":");
Console.WriteLine (PI.GetValue(inputs[i], null));
} }
return guid;
} }
}
using System;
using System.Collections.Generic;
using System.Text;
using System.ServiceModel ;
using System.ServiceModel.Description;
namespace AOPAndWCF
{
public class MyServiceHost:ServiceHost
{
/// <summary>
/// 构造函数
/// </summary>
/// <param name="serviceType">服务类型</param>
/// <param name="baseAddresses">基地址</param>
public MyServiceHost(Type serviceType, params Uri[] baseAddresses) : base(serviceType, baseAddresses) { } /// <summary>
/// 应用配置文件设置
/// </summary>
protected override void ApplyConfiguration()
{
base.ApplyConfiguration();
//加入参数检查服务
addguidvalidation(); } /// <summary>
///加入参数检查服务
/// </summary>
private void addguidvalidation()
{
//加入参数检查服务
int endpointscount = this.Description.Endpoints.Count;
MyParameterInspector mypi = new MyParameterInspector();
for (int i = 0; i < endpointscount; i++)
{
if (this.Description.Endpoints[i].Contract.Name != "IMetadataExchange")
{
int Operationscount = this.Description.Endpoints[i].Contract.Operations.Count;
for (int j = 0; j < Operationscount; j++)
{
this.Description.Endpoints[i].Contract.Operations[j].Behaviors.Add(mypi);
}
}
}
} }
}
using System;
using System.Collections.Generic;
using System.Text; namespace AOPAndWCF
{
class Program
{
static void Main(string[] args)
{
MyServiceHost msh = new MyServiceHost(typeof(WcfServiceLibrary.Service1 ));
msh.Open();
Console.WriteLine ("服务已开启,回车关闭服务");
Console.ReadLine();
msh.Close(); }
}
}
Extending WCF using IServiceBehavior, IOperationBehavior, and IParameterInspector的更多相关文章
- Wcf实现IServiceBehavior拓展机制
IServiceBehavior接口 描述:提供一种在整个服务内修改或插入自定义拓展机制: 命名空间: System.ServiceModel.Description程序集: System.Ser ...
- 真实世界:使用WCF扩展记录服务调用时间
WCF 可扩展性 WCF 提供了许多扩展点供开发人员自定义运行时行为. WCF 在 Channel Layer 之上还提供了一个高级运行时,主要是针对应用程序开发人员.在 WCF 文档中,它常被称为服 ...
- WCF扩展
WCF 可扩展性 WCF 提供了许多扩展点供开发人员自定义运行时行为. WCF 在 Channel Layer 之上还提供了一个高级运行时,主要是针对应用程序开发人员.在 WCF 文档中,它常被称为服 ...
- 使用WCF扩展记录服务调用时间
随笔- 64 文章- 0 评论- 549 真实世界:使用WCF扩展记录服务调用时间 WCF 可扩展性 WCF 提供了许多扩展点供开发人员自定义运行时行为. WCF 在 Channel Lay ...
- WCF扩展记录服务调用时间
WCF 提供了许多扩展点供开发人员自定义运行时行为. WCF 在 Channel Layer 之上还提供了一个高级运行时,主要是针对应用程序开发人员.在 WCF 文档中,它常被称为服务模型层(Serv ...
- WCF笔记
http://msdn.microsoft.com/en-us/library/system.servicemodel.dispatcher.iparameterinspector.aftercall ...
- 转 使用IParameterInspector, IOperationBehavior,Attribute(参数检查器、操作行为接口和标签)扩展WCF操作行为
public class EntryIdInspector : IParameterInspector { public int intParamIndex { get; set; } string ...
- IServiceBehavior IContractBehavior IEndpointBehavior IOperationBehavior
using System; using System.Collections.ObjectModel; using System.Reflection; using System.ServiceMod ...
- WCF自定义扩展,以实现aop!
引用地址:https://msdn.microsoft.com/zh-cn/magazine/cc163302.aspx 使用自定义行为扩展 WCF Aaron Skonnard 代码下载位置: S ...
随机推荐
- 改变jupyter notebook的主题背景
https://study.163.com/provider/400000000398149/index.htm?share=2&shareId=400000000398149( 欢迎关注博 ...
- Flutter页面跳转返回数据
Dart中的异步请求和等待和ES6中的方法很像,直接使用async...await就可以实现. 核心代码: _navigateToAddress(BuildContext context) async ...
- phpexcel 导出excel无法打开,提示文件格式或文件名无效,文件损毁,解决办法
使用过很多次phpexcel了,有时需要保存文件到磁盘,有时需要浏览器弹出下载.保存到磁盘一半不会出现问题,关键是浏览器弹出保存,经常会发生导出的excel文件无法打开,提示文件格式或文件名无效,文件 ...
- python设置socket的超时时间(可能使用locust压测千级并发的时候要用到,先记录在此)
在使用urllib或者urllib2时,有可能会等半天资源都下载不下来,可以通过设置socket的超时时间,来控制下载内容时的等待时间. 如下python代码 import socket timeou ...
- spring 使用@Bean装配Bean
通过@Component装配Bean,但是@Component只能注解在类上,不能注解到方法上.对于Java而言,大部分的开发都需要引入第三方的包(jar文件),而且往往并没有这些包的源码,这时候将无 ...
- SqlServer触发器常用语法AFTER、INSTEAD OF及其详解
先创建一个简单的触发器 CREATE TRIGGER trigger_name ON table_name [WITH ENCRYPTION] FOR | AFTER | INSTEAD OF [DE ...
- curl实现put请求
<?php function curlrequest($url,$data,$method='post'){ $ch = curl_init(); //初始化CURL句柄 curl_setopt ...
- FormsAuthentication使用指南
配置安全鉴别 鉴别是指鉴定来访用户是否合法的过程.ASP.NET Framework支持三种鉴别类型: Windows鉴别: NET Passport鉴别: Forms鉴别. 对于某一特定的应用程序, ...
- 使用docker搭建FastDFS文件系统
1.首先下载FastDFS文件系统的docker镜像 docker search fastdfs 2.使用docker镜像构建tracker容器(跟踪服务器,起到调度的作用): docker run ...
- 17、vue-cli3 js项目中引入ts混用(typeScript)
说明: vue3.0搭建的项目,不过没有引入ts,后来需要用到一个插件是用ts写的,所以vue要用到ts... 一.安装typescript及loader npm install typescript ...