Как мне вызвать ChannelFactory <TChannel>динамически? - PullRequest
1 голос
/ 02 января 2012

Мне нужно позвонить ChannelFactory<TChannel> классу.Но код ниже для ChannelFactory класса.Понятия не имею, как позвонить ChannelFactory<TChannel>.Пожалуйста, предложите, как я могу назвать ChannelFactory<TChannel> класс.

string interfaceName = "Test";  
Type myInterfaceType = Type.GetType(interfaceName);
var factoryType = typeof(ChannelFactory<>).MakeGenericType(myInterfaceType);
var factoryCtr = factoryType.GetConstructor(new[] { typeof(BasicHttpBinding), typeof(EndpointAddress) });
ChannelFactory factorry = factoryCtr.Invoke(new object[] { new BasicHttpBinding(), new EndpointAddress(cmbpath.SelectedItem.ToString()) }) as ChannelFactory;

Ответы [ 2 ]

2 голосов
/ 30 мая 2013

Итак, у вас есть 2 проблемы: динамически создавать ChannelFactory и динамически вызывать его, и Reflection - решение для них обоих.

И ваш код, и код Ваутера хороши для динамического создания объекта ChannelFactory с помощью Reflection, проблема в том, что поскольку тип неизвестен во время компиляции, вы не можете привести его к типу, и все, что вы можете получить, - это не универсальный ( бесполезно) ChannelFactory.

Итак, чтобы создать ваш конкретный канал и затем вызывать методы для него, вы можете пройти долгий путь, снова используя Reflection самостоятельно ... или позволить самой среде выполнения использовать Reflection от вашего имени с помощью динамических средств. То есть измените свою последнюю (или последнюю) строку Ваутера на:

dynamic factory = factoryCtr.Invoke(.....

или

dynamic factory = Activator.CreateInstance(...

без необходимости включать "as ChannelFactory" в конце.

, а затем просто используйте:

dynamic channel = factory.CreateChannel();
//and now invoke the methods in your Interface
channel.TestMethod...
2 голосов
/ 02 января 2012

Попробуйте следующий код в консольном приложении:

using System;
using System.ServiceModel;

namespace ExperimentConsoleApp
{
    class Program
    {
        static void Main()
        {
            string endPoint = "http://localhost/service.svc";

            string interfaceName = "ExperimentConsoleApp.ITest";
            Type myInterfaceType = Type.GetType(interfaceName);
            var factoryType = typeof(ChannelFactory<>).MakeGenericType(myInterfaceType);
            ChannelFactory factory = Activator.CreateInstance(factoryType, new object[] { new BasicHttpBinding(), new EndpointAddress(endPoint) }) as ChannelFactory;
        }
    }

    [ServiceContract]
    public interface ITest
    { }
}

Несколько моментов:

  • Используйте Activator.CreateInstance, чтобы создать тип через отражение
  • Вы должны полностью указать свой interfaceName, чтобы убедиться, что отражение может его найти
  • Украсить интерфейс службы с помощью ServiceContract
  • Убедитесь, что ваша конечная точка имеет правильный формат
...