Вызовите операцию, которая была динамически добавлена ​​в контракт на обслуживание. - PullRequest
0 голосов
/ 08 марта 2012

У меня есть контракт на обслуживание WCF (скажем, IService1), к которому я динамически добавляю операцию, как описано здесь . Как я могу вызвать динамически добавляемую операцию со стороны клиента, когда у меня есть только прозрачный прокси-сервер IService1 и IClientChannel, созданный через ClientChannelFactory?

Обновление

Я могу получить RealProxy от прозрачного прокси, возвращенного из ChannelFactory, используя этот метод .

var realProxy = System.Runtime.Remoting.RemotingServices.GetRealProxy( transparentProxy );

Можно ли вызвать realyProxy.Invoke(IMessage) с поддельным сообщением, чтобы обмануть прокси в вызове динамически добавляемого метода?

1 Ответ

0 голосов
/ 08 марта 2012

Замените GeneratePingMethod следующим:

private static void GenerateNewPingMethod(ServiceHost sh)
{
    foreach (var endpoint in sh.Description.Endpoints)
    {

        ContractDescription contract = endpoint.Contract;

        OperationDescription operDescr = new OperationDescription("Ping", contract);

        MessageDescription inputMsg = new MessageDescription(contract.Namespace + contract.Name + "/Ping", MessageDirection.Input);

        MessageDescription outputMsg = new MessageDescription(contract.Namespace + contract.Name + "/PingResponse", MessageDirection.Output);

        MessagePartDescription retVal = new MessagePartDescription("PingResult", contract.Namespace);

        retVal.Type = typeof(DateTime);

        outputMsg.Body.WrapperName = "PingResponse";
        outputMsg.Body.WrapperNamespace = contract.Namespace;
        outputMsg.Body.ReturnValue = retVal;


        operDescr.Messages.Add(inputMsg);
        operDescr.Messages.Add(outputMsg);
        operDescr.Behaviors.Add(new DataContractSerializerOperationBehavior(operDescr));
        operDescr.Behaviors.Add(new PingImplementationBehavior());
        contract.Operations.Add(operDescr);
    }
}

и создайте своих клиентов так:

// this is your base interface
[ServiceContract]
public interface ILoginService
{
    [OperationContract(Action = "http://tempuri.org/LoginService/Login", Name = "Login")]
    bool Login(string userName, string password);
}

[ServiceContract]
public interface IExtendedInterface : ILoginService
{
    [OperationContract(Action = "http://tempuri.org/LoginService/Ping", Name="Ping")]
    DateTime Ping();
}


class Program
{
    static void Main(string[] args)
    {
        IExtendedInterface channel = null;
        EndpointAddress endPointAddr = new EndpointAddress("http://localhost/LoginService");
        BasicHttpBinding binding = new BasicHttpBinding();

        channel = ChannelFactory<IExtendedInterface>.CreateChannel(binding, endPointAddr);

        if (channel.Login("test", "Test"))
        {
            Console.WriteLine("OK");
        }
        DateTime dt = channel.Ping();

        Console.WriteLine(dt.ToString());

    }
}
...