더 나은 IParameterInspector을 사용하는 것입니다 수 있습니다. 그렇게 할 수는 있지만 매개 변수의 값을 얻기 위해 메시지를 읽은 후에는 메시지가 으로 사용되었으므로 메시지를 WCF로 전달하기 전에 다시 작성해야합니다 (메시지 검사기에서 요청 참조로 전달되므로 실제로 소비해야하는 경우이를 대체 할 수 있습니다).
@burning_LEGION에서 언급했듯이 매개 변수 관리자는 시나리오에 가장 적합한 옵션입니다. Inspector 자체에는 매개 변수 이름이 없지만 매개 변수 관리자를 추가하는 데 사용할 동작 설명에서 가져올 수 있습니다. 아래 코드는 어떻게 수행 할 수 있는지 보여줍니다.
public class StackOverflow_15637994
{
[ServiceContract]
public interface ITest
{
[OperationContract]
string Echo(string text);
[OperationContract]
int Execute(string op, int x, int y);
[OperationContract]
bool InOutAndRefParameters(int x, ref int y, out int z);
}
public class Service : ITest
{
public string Echo(string text)
{
return text;
}
public int Execute(string op, int x, int y)
{
return x + y;
}
public bool InOutAndRefParameters(int x, ref int y, out int z)
{
z = y;
y = x;
return true;
}
}
public class MyInspector : IParameterInspector
{
string[] inputParameterNames;
string[] outputParameterNames;
public MyInspector(string[] inputParameterNames, string[] outputParameterNames)
{
this.inputParameterNames = inputParameterNames;
this.outputParameterNames = outputParameterNames;
}
public void AfterCall(string operationName, object[] outputs, object returnValue, object correlationState)
{
Console.WriteLine("Operation: {0}", operationName);
Console.WriteLine(" Result: {0}", returnValue);
for (int i = 0; i < outputs.Length; i++)
{
Console.WriteLine(" [out] {0}: {1}", this.outputParameterNames[i], outputs[i]);
}
}
public object BeforeCall(string operationName, object[] inputs)
{
Console.WriteLine("Operation: {0}", operationName);
for (int i = 0; i < inputs.Length; i++)
{
Console.WriteLine(" {0}: {1}", this.inputParameterNames[i], inputs[i]);
}
return null;
}
}
public class MyBehavior : IEndpointBehavior
{
public void AddBindingParameters(ServiceEndpoint endpoint, BindingParameterCollection bindingParameters)
{
}
public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime)
{
}
public void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher)
{
foreach (var operation in endpoint.Contract.Operations)
{
string[] inputParamNames = operation.Messages[0].Body.Parts
.OrderBy(mpd => mpd.Index)
.Select(mpd => mpd.Name)
.ToArray();
string[] outputParamNames = null;
if (operation.Messages.Count > 1)
{
outputParamNames = operation.Messages[1].Body.Parts
.OrderBy(mpd => mpd.Index)
.Select(mpd => mpd.Name)
.ToArray();
}
MyInspector inspector = new MyInspector(inputParamNames, outputParamNames);
endpointDispatcher.DispatchRuntime.Operations[operation.Name].ParameterInspectors.Add(inspector);
}
}
public void Validate(ServiceEndpoint endpoint)
{
}
}
public static void Test()
{
string baseAddress = "http://" + Environment.MachineName + ":8000/Service";
ServiceHost host = new ServiceHost(typeof(Service), new Uri(baseAddress));
ServiceEndpoint endpoint = host.AddServiceEndpoint(typeof(ITest), new BasicHttpBinding(), "");
endpoint.Behaviors.Add(new MyBehavior());
host.Open();
Console.WriteLine("Host opened");
ChannelFactory<ITest> factory = new ChannelFactory<ITest>(new BasicHttpBinding(), new EndpointAddress(baseAddress));
ITest proxy = factory.CreateChannel();
proxy.Echo("Hello");
proxy.Execute("foo", 2, 5);
int z;
int y = 2;
proxy.InOutAndRefParameters(3, ref y, out z);
((IClientChannel)proxy).Close();
factory.Close();
Console.Write("Press ENTER to close the host");
Console.ReadLine();
host.Close();
}
}
덕분에, 나는 IParameterInspector을 사용하고 싶어하지만 IParameterInspector를 사용하여 사이트 이름 인 매개 변수를 찾을 수 없습니다, 그래서 그것은 입력 매개 변수 이름 만 값이 없습니다. –
반사 - 문자열 메서드 이름 –
에 의한 매개 변수 이름을 사용하면 메시지에서 Xml XPath보다 더 효율적입니까? –