Веб-сервисы Dynamic Invoker вопрос - PullRequest
3 голосов
/ 30 марта 2009

Я играл с Атрибутами через веб-сервисы и видел, что класс SoapHttpClientProtocol должен определять Атрибут WebServiceBinding.

Наблюдая за этим вопросом , кажется, что невозможно изменить атрибуты во время выполнения, как я могу добиться динамического вызова веб-службы, меняющего этот атрибут во время выполнения? это возможно?

[Изменить] Я ищу подход для динамического вызова «универсального стиля», а не для изменения атрибута WebServiceBinding.

Это, в двух словах, мой класс:

using System.Web.Services;
using System.Web.Services.Protocols;

namespace Whatever {
    [WebServiceBinding(Name = "", Namespace = "")]
    public class WebServiceInvoker : SoapHttpClientProtocol {
        public WebServiceInvoker(string url, string ns, string bindingName) {

            ChangeNamespace(ns);
            ChangeBinding(bindingName);
            Url = url;
            // credentials, etc
    }
        public void ChangeNamespace(string ns) {
            var att = GetType().GetCustomAttributes(typeof (WebServiceBindingAttribute), true);         
            if (att.Length > 0) {
                // doesn't work
                ((WebServiceBindingAttribute)att[0]).Namespace = ns;
            }
        }
        private void ChangeBinding(string bindingName) {
            var att = GetType().GetCustomAttributes(typeof(WebServiceBindingAttribute), true);

            if (att.Length > 0) {
                // doesn't work
                ((WebServiceBindingAttribute)att[0]).Name = bindingName;
            }
        }
        public object[] MakeInvoke(string method, object[] args) {
            var res = Invoke(method, method);
            return res;
        }

        public TRet InvokeFunction<TRet>(string method) {
            //Funcion<T1, T2, T3, TRet>
            var res = Invoke(method, null);
            return MyUtils.ForceCast<TRet>(res);
        }
        public TRet InvokeFunction<T1, TRet>(string method, T1 par1) {
            //Funcion<T1, T2, T3, TRet>
            var args = new object[] { par1 };
            var res = Invoke(method, args);
            return MyUtils.ForceCast<TRet>(res);
        }
        public TRet InvokeFunction<T1, T2, TRet>(string method, T1 par1, T2 par2) {
            //Funcion<T1, T2, T3, TRet>
            var args = new object[] { par1, par2 };
            var res = Invoke(method, args);
            return MyUtils.ForceCast<TRet>(res);
        }
        public TRet InvokeFunction<T1, T2, T3, TRet>(string method, T1 par1, T2 par2, T3 par3) {
            //Funcion<T1, T2, T3, TRet>
            var args = new object[] {par1, par2, par3};
            var res = Invoke(method, args);
            return MyUtils.ForceCast<TRet>(res);
        }

        public void InvokeAction(string metodo) {
            //Funcion<T1, T2, T3, TRet>
            Invoke(method, null);
        }
        public void InvokeAction<T1>(string method, T1 par1) {
            //Funcion<T1, T2, T3, TRet>
            var args = new object[] { par1 };
            Invoke(method, args);
        }
        public void InvokeAction<T1, T2>(string method, T1 par1, T2 par2) {
            //Funcion<T1, T2, T3, TRet>
            var args = new object[] { par1, par2 };
            Invoke(method, args);
        }
        public void InvokeAction<T1, T2, T3>(string method, T1 par1, T2 par2, T3 par3) {
            //Funcion<T1, T2, T3, TRet>
            var args = new object[] { par1, par2, par3 };
            Invoke(method, args);
        }
    }
}

[Изменить] Я хотел бы назвать свой класс так:

var miProxy = new WebServiceInvoker("http://webServiceLocation", "ns", "Binding");
var res = miProxy.InvokeFunction<string, string, Entity>("MyWebMethod", stringPar1, stringPar2);

Ответы [ 5 ]

2 голосов
/ 11 апреля 2009

Есть еще один действительно хороший пример этого в Программирование Crows. Он описывает класс, который позволяет вам вызывать произвольные сообщения в любом веб-сервисе. Это на самом деле довольно гладко. Надеюсь, это поможет.

2 голосов
/ 30 марта 2009

Вы не можете изменять атрибуты во время выполнения. Это просто метаданные в коде IL, и если вы запрашиваете атрибут, создается и возвращается экземпляр указанного класса атрибута. Таким образом, фактические экземпляры атрибута не существуют, пока вы не запросите их.

Возможно, можно изменить сборку с помощью отражения, но я не уверен, и это, вероятно, вам не понравится.

1 голос
/ 30 июня 2011
1 голос
/ 31 марта 2009

Как вы заявили, вы не можете изменять атрибут во время выполнения.

Единственный способ добиться эффекта добавления / удаления / изменения атрибута во время выполнения - это создать новый тип, который обертывает фактический тип. Однако прокси-классы времени выполнения имеют накладные расходы (сложность разработки и производительность) и редко когда-либо стоят в производственном коде.

Я бы, однако, взглянул на правильность утверждения:

Необходим класс SoapHttpClientProtocol определить WebServiceBinding Атрибут.

Microsoft обычно дает вам по крайней мере два способа снять шкуру с кошки. Я готов поспорить, что вышесказанное не является категорически правдой. Вероятно, есть другой способ выполнить то, что вы пытаетесь сделать.

То, что я пытаюсь сказать, таково: вы могли бы лаять не на то дерево, следуя маршруту атрибута времени выполнения.

1 голос
/ 30 марта 2009

Я не совсем уверен, что вы пытаетесь сделать здесь ... вы пытаетесь создать веб-сервис, который поддерживает вызов произвольных методов вызывающей стороной? Если да, то вот пример этого на практике: Создание динамического веб-сервиса для упрощения кода

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...