powered by simpleCommunicator - 2.0.29     © 2024 Programmizd 02
Map
Форумы / WCF, Web Services, Remoting [игнор отключен] [закрыт для гостей] / Клиент->WCF Service1, ->WCF Service2,->WCF Service3
11 сообщений из 11, страница 1 из 1
Клиент->WCF Service1, ->WCF Service2,->WCF Service3
    #40062525
Ролг Хупин
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Есть винформс клиент, он работает с ->WCF Service1, т.е. есть референсе на сервис и


public MyServiceReference.MyDataServiceClient client;

с этим клиентом много кода.
Суть вопроса:
Как сделать так, чтобы приложение работало с несколькими версиями сервиса?

Т.е. сервисы отличается некоторыми параметрами, как сделать как-то так, скажем цепляю референсы на три версии сервиса

public MyServiceReference.MyDataServiceClient1 client1;
public MyServiceReference.MyDataServiceClient2 client2;
public MyServiceReference.MyDataServiceClient3 client3;

Но в коде везде используется переменная client, можно ли использовать одну переменную client? или как-то по-другому?
...
Рейтинг: 0 / 0
Клиент->WCF Service1, ->WCF Service2,->WCF Service3
    #40062532
felix_ff
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ролг Хупин
Есть винформс клиент, он работает с ->WCF Service1, т.е. есть референсе на сервис и


public MyServiceReference.MyDataServiceClient client;

с этим клиентом много кода.
Суть вопроса:
Как сделать так, чтобы приложение работало с несколькими версиями сервиса?

Т.е. сервисы отличается некоторыми параметрами, как сделать как-то так, скажем цепляю референсы на три версии сервиса

public MyServiceReference.MyDataServiceClient1 client1;
public MyServiceReference.MyDataServiceClient2 client2;
public MyServiceReference.MyDataServiceClient3 client3;

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


чего?
расшифруйте как вы собрались использовать одну переменную client на три разных класса?

из того что я понял вам нужна какая то обертка которая будет создавать тот или иной инстанс прокси-клиента или нет?
...
Рейтинг: 0 / 0
Клиент->WCF Service1, ->WCF Service2,->WCF Service3
    #40062589
Ролг Хупин
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
felix_ff
Ролг Хупин
Есть винформс клиент, он работает с ->WCF Service1, т.е. есть референсе на сервис и


public MyServiceReference.MyDataServiceClient client;

с этим клиентом много кода.
Суть вопроса:
Как сделать так, чтобы приложение работало с несколькими версиями сервиса?

Т.е. сервисы отличается некоторыми параметрами, как сделать как-то так, скажем цепляю референсы на три версии сервиса

public MyServiceReference.MyDataServiceClient1 client1;
public MyServiceReference.MyDataServiceClient2 client2;
public MyServiceReference.MyDataServiceClient3 client3;

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


чего?
расшифруйте как вы собрались использовать одну переменную client на три разных класса?

из того что я понял вам нужна какая то обертка которая будет создавать тот или иной инстанс прокси-клиента или нет?


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

Другими словами - какой подход можно использовать?

Кроме лобового:
if(version==1)
client1....
else
if(version==2)
client2...
else
client3...
...
Рейтинг: 0 / 0
Клиент->WCF Service1, ->WCF Service2,->WCF Service3
    #40062590
felix_ff
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ролг Хупин,

ну используйте dynamic обойдете проверку статической типизации тогда.
...
Рейтинг: 0 / 0
Клиент->WCF Service1, ->WCF Service2,->WCF Service3
    #40062639
Сон Веры Павловны
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Все классы, создаваемые при добавлении service reference, студия объявляет как partial - т.е. им можно задать свою иерархию интерфейсов.
Допустим, в проект импортировано 3 версии сервиса с неймспейсами FooServiceReference1, FooServiceReference2, FooServiceReference3. Созданный при импорте код выглядит как-то так (атрибуты для простоты убрал):
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
namespace MyProject.FooServiceReference1
{
  public interface IFooService
  {
    string Foo();
  }

  public partial class FooServiceClient : System.ServiceModel.ClientBase<MyProject.FooServiceReference1.IFooService>, MyProject.FooServiceReference1.IFooService {
    public FooServiceClient() {
    }
    public FooServiceClient(string endpointConfigurationName) : 
      base(endpointConfigurationName) {
    }
    .............
    public string Foo() {
      return base.Channel.Foo();
    }
  }
}

namespace MyProject.FooServiceReference2
{
  public interface IFooService
  {
    string Foo();
    int Bar();
  }
  public partial class FooServiceClient : System.ServiceModel.ClientBase<MyProject.FooServiceReference2.IFooService>, MyProject.FooServiceReference2.IFooService {
    public FooServiceClient() {
    }
    public FooServiceClient(string endpointConfigurationName) : 
      base(endpointConfigurationName) {
    }
    .............
    public string Foo() {
      return base.Channel.Foo();
    }

    public int Bar() {
      return base.Channel.Bar();
    }
  }
}

namespace MyProject.FooServiceReference3
{
  public interface IFooService
  {
    string Foo();
    int Bar();
    void Zot();
  }
  public partial class FooServiceClient : System.ServiceModel.ClientBase<MyProject.FooServiceReference3.IFooService>, MyProject.FooServiceReference3.IFooService {
    public FooServiceClient() {
    }
    public FooServiceClient(string endpointConfigurationName) : 
      base(endpointConfigurationName) {
    }
    .............
    public string Foo() {
      return base.Channel.Foo();
    }

    public int Bar() {
      return base.Channel.Bar();
    }

    public void Zot() {
      base.Channel.Zot();
    }
  }
}


Где-нибудь сбоку объявляем свои интерфейсы с тем же набором методов, что и у сервисов, и унаследованные друг от друга:
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
namespace MyProject.FooServiceCommon
{
  public interface IFoo
  {
    string Foo();
  }

  public interface IBar: IFoo
  {
    int Bar();
  }

  public interface IZot : IBar
  {
    void Zot();
  }
}


и в отдельном исходнике привязываем интерфейсы к классам сервисов:
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
namespace MyProject.FooServiceReference1
{
  public partial class FooServiceClient : MyProject.FooServiceCommon.IFoo {}
}
namespace MyProject.FooServiceReference2
{
  public partial class FooServiceClient : MyProject.FooServiceCommon.IBar {}
}
namespace MyProject.FooServiceReference3
{
  public partial class FooServiceClient : MyProject.FooServiceCommon.IZot {}
}


Теперь этим хозяйством можно пользоваться через общую иерархию интерфейсов:
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
namespace MyProject.FooServiceCommon
{
  public static class FooServiceFactory
  {
    public static T Create<T>()
      where T: class, IFoo
    {
      if (typeof(T) == typeof(IFoo))
        return (T)(IFoo)new MyProject.FooServiceReference1.FooServiceClient("MyBinding1_IFooService");
      if (typeof(T) == typeof(IBar))
        return (T)(IBar)new MyProject.FooServiceReference2.FooServiceClient("MyBinding2_IFooService");
      if (typeof(T) == typeof(IZot))
        return (T)(IZot)new MyProject.FooServiceReference3.FooServiceClient("MyBinding3_IFooService");
      throw new InvalidOperationException($"Type {typeof(T)} is not supported");
    }
  }
}


(ну, или там запихать экземпляры сервисов в какой-нить диконтейнер по типам реализуемых интерфейсов, итп.)
Код: c#
1.
2.
3.
4.
5.
6.
7.
static void Main()
{
  var zot = FooServiceFactory.Create<IZot>();
  Console.WriteLine(zot.Foo());
  Console.WriteLine(zot.Bar());
  zot.Zot();
}
...
Рейтинг: 0 / 0
Клиент->WCF Service1, ->WCF Service2,->WCF Service3
    #40062712
Ролг Хупин
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
2 Сон Веры Павловны,
ух, жесть, спасибо, ушел разбираться, если что - вернусь с вопросами
...
Рейтинг: 0 / 0
Клиент->WCF Service1, ->WCF Service2,->WCF Service3
    #40064224
Ролг Хупин
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Сон Веры Павловны,

вопрос:
Как быть если мне нужна глобальная переменная zot?
Т.е. я сначала определяюсь с какой версией сервиса я работаю, потом вызываю Factory

Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
static void Main()
{
 // var zot = FooServiceFactory.Create<IZot>();

if(kakto_mozhet_iz_konfig_file==1)
   zot = FooServiceFactory.Create<IZot>();
else
   zot = FooServiceFactory.Create<IBar>();

  Console.WriteLine(zot.Foo());
  Console.WriteLine(zot.Bar());
  zot.Zot();
}
...
Рейтинг: 0 / 0
Клиент->WCF Service1, ->WCF Service2,->WCF Service3
    #40064419
Ролг Хупин
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
felix_ff
Ролг Хупин,

ну используйте dynamic обойдете проверку статической типизации тогда.


как это проделать в свете моего вопроса юзеру Сон Веры Павловны?

Т.е. если локальная переменная ,тогда сойдет так

Код: c#
1.
2.
3.
4.
5.
6.
7.
static void Main()
{
  var zot = FooServiceFactory.Create<IZot>(); \\<---------
  Console.WriteLine(zot.Foo());
  Console.WriteLine(zot.Bar());
  zot.Zot();
}



а если мне нужна глобальная переменная клиент сервиса, которая будет создана
как один из типов
FooServiceFactory.Create<IZot>();

и будет использоваться затем в других функциях - как объявить?
...
Рейтинг: 0 / 0
Клиент->WCF Service1, ->WCF Service2,->WCF Service3
    #40064434
Сон Веры Павловны
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ролг Хупин

а если мне нужна глобальная переменная клиент сервиса, которая будет создана
как один из типов
FooServiceFactory.Create<IZot>();

и будет использоваться затем в других функциях - как объявить?

Выше же писал: использовать диконтейнер. Ну, там нинжект какой-нибудь:
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
public static class ServiceFactory
{
  static readonly IKernel resolver;
  static ServiceInjector()
  {
    resolver = new StandardKernel(
      new CommonModule()
    );
  }

  public static T Get<T>(params IParameter[] arguments)
  {
    return resolver.Get<T>(arguments);
  }
  
  class CommonModule : NinjectModule
  {
    public override void Load()
    {
      Bind<IZot>().ToConstant(new MyProject.FooServiceReference3.FooServiceClient("MyBinding3_IFooService")).InSingletonScope();
    }
  }
}


и дальше уж как нравится - инжектить клиента как зависимость, если хочется по фэншую, или дергать ServiceFactory.Get<IZot>(), если хочется по рабоче-крестьянски.
Autofac, насколько я помню, такие вещи позволяет определять в конфиге.
...
Рейтинг: 0 / 0
Клиент->WCF Service1, ->WCF Service2,->WCF Service3
    #40064445
Ролг Хупин
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Сон Веры Павловны
Ролг Хупин

а если мне нужна глобальная переменная клиент сервиса, которая будет создана
как один из типов
FooServiceFactory.Create<IZot>();

и будет использоваться затем в других функциях - как объявить?

Выше же писал: использовать диконтейнер. Ну, там нинжект какой-нибудь:
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
public static class ServiceFactory
{
  static readonly IKernel resolver;
  static ServiceInjector()
  {
    resolver = new StandardKernel(
      new CommonModule()
    );
  }

  public static T Get<T>(params IParameter[] arguments)
  {
    return resolver.Get<T>(arguments);
  }
  
  class CommonModule : NinjectModule
  {
    public override void Load()
    {
      Bind<IZot>().ToConstant(new MyProject.FooServiceReference3.FooServiceClient("MyBinding3_IFooService")).InSingletonScope();
    }
  }
}


и дальше уж как нравится - инжектить клиента как зависимость, если хочется по фэншую, или дергать ServiceFactory.Get<IZot>(), если хочется по рабоче-крестьянски.
Autofac, насколько я помню, такие вещи позволяет определять в конфиге.


ясно, еще один вопрос:

в реальной жизни я добавляю ссылку на сервис и на сервис2.
Результат генерации: два фолдера с кучей файлов, включая в каждом Reference.cs

Я понял, в чем разница между моим и вашим описанием.
Мои обе ссылки на сервисы независимы, т.е. они не выведены из общих интерфейсов и классов.
Поэтому,такое определение

Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
public static class DAServiceFactory
    {
        public static T Create<T>(Binding bin, EndpointAddress address)
            where T : class, 
            IMySReference.IDAService 
            //,IMySReference1.IDAService
        {
            if (typeof(T) == typeof(IMySReference.IDSAervice))
                return (T)(IMySReference.IDSAervice)new IMySReference.DAServiceClient(bin, address);

            if (typeof(T) == typeof(IMySReference1.IDAervice))
                return (T)(IMTSReference1.IDAccessService)new IMySReference1.DAServiceClient(bin, address);

            throw new InvalidOperationException($"Type {typeof(T)} is not supported");
        }



Вызываю:
myclient = DAServiceFactory<IMySReference1.IDAService>(bin, ep)

пишет ошибку,
авторThe type 'IMySReference1.IDAService' cannot be used as type parameter 'T' in the generic type or method 'DataAccessServiceFactory.Create<T>(Binding, EndpointAddress)'. There is no implicit reference conversion from 'IMySReference1.IDAService' to 'IMySReference.IDAService'.



т.е. понимаю, что как в вашем примере интерфес должен быть выведен из общего, но я использую файлы сгенерированные wsdl и не хотелось бы руками там шастать
...
Рейтинг: 0 / 0
Клиент->WCF Service1, ->WCF Service2,->WCF Service3
    #40064454
Сон Веры Павловны
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ролг Хупин
т.е. понимаю, что как в вашем примере интерфес должен быть выведен из общего, но я использую файлы сгенерированные wsdl и не хотелось бы руками там шастать

Там не надо шастать руками. Я же выше писал - то что создается по wsdl, создается с модификатором partial. Это позволяет в любом расположении в том же проекте создать исходник, в нем в аналогичном неймспейсе создать класс с тем же именем и модификатором partial, и у него задать нужные интерфейсы. Автосгененированные исходники при этом останутся нетронутыми.
...
Рейтинг: 0 / 0
11 сообщений из 11, страница 1 из 1
Форумы / WCF, Web Services, Remoting [игнор отключен] [закрыт для гостей] / Клиент->WCF Service1, ->WCF Service2,->WCF Service3
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]