дуплексный сервис wcf теряет связь с клиентом

Я застрял в вопросе в течение 2 недель.

Предположим, у нас есть дуплексная служба WCF и клиентское приложение, которое вызывает эту службу.

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

ДОГОВОР ДУПЛЕКСНОГО ОБСЛУЖИВАНИЯ:

[ServiceContract(SessionMode=SessionMode.Required,CallbackContract=typeof(ICallback))]
public interface IService{

 [OperationContract(IsOneWay = true)]
 void GetDataFromService();

}

ДУПЛЕКСНЫЙ ОБРАТНЫЙ ЗВОНОК:

public interface ICallback{

[OperationContract(IsOneWay = true)]
void ReceiveMessage(string message);

}

Внедрение ДУПЛЕКС СЕРВИСА

public class Service : IService{

//... here a reference to the Callback endpoint

void GetDataFromService(){

callBackEndPoint.ReceiveMessage("Service was called.");
}
}

МОЙ КЛАСС, РЕАЛИЗУЮЩИЙ ОБРАТНЫЙ ЗВОНОК:

public class MyCallBackClass : ICallback, Widnows.Form
{
IService service;

public MyCallBackClass (){

InstanceContext instanceContext = new InstanceContext(this);

this.service = new ServiceClient(instanceContext);

}

public ReceiveMessage(string message){

this.textBoxMessage.Text = message;
//here I want to stress that I would like my CallBack object to be a Form or WPF Form
//so that I can react on callbacks by modyfing the Controls like TextBox, ListBox directly

}

}

Теперь в приложении я вынужден создать экземпляр службы в конструкторе объекта, реализующего интерфейс обратного вызова, допустим, это форма или форма WPF (как показано ниже):

public void Main(string[] args){

MyCallBackClass myWindow = new MyCallBackClass();

myWindow.GetDataFromService();

}

Я хотел бы ПРОЙТИ СЕРВИС в конструкторе обработчика обратного вызова, как показано ниже:

public void Main(string[] args){

Iservice service = new ServiceClient();// but what about the InstanceContext that is the MyCallBackClass object...???

MyCallBackClass myWindow = new MyCallBackClass(service);

myWindow.GetDataFromService();

}

И, конечно же, конструктор класса MyCallBackClass изменится на это:

public class MyCallBackClass : ICallback, Widnows.Form
{
IService service;

public MyCallBackClass (IService _service){

InstanceContext instanceContext = new InstanceContext(this);

this.service = _service;

...
}

Так что я могу внедрить любой тип службы, реализующей интерфейс IService, в клиентский класс, а также легко протестировать клиентский класс, высмеяв службу. К сожалению, я сталкиваюсь с ПЕТЛЕЙ ЗАВИСИМОСТИ. InstanceContext зависит от MyCallBackClass, который зависит от IService, который зависит от InstanceContext ...

Не могли бы вы попытаться понять и направить меня в любом направлении, которое могло бы решить эту проблему?


person Big Dizzle    schedule 12.09.2013    source источник
comment
Вы здесь много прыгаете ... так что трудно понять, что вы хотите и где находится каждый код, но позвольте мне попытаться прояснить для себя: похоже, ваш клиент и ваш сервис - это одно и то же? Вы хотите создать способ создания модели pub / sub для услуги ... это правильно?   -  person Justin Pihony    schedule 12.09.2013
comment
Да, я знал, что мое описание было немного неясным, хотя я не мог выразить его другими словами ... Ну, клиент и сервис - это не одно и то же ... Подводя итог, я хочу создать потерю связи между клиентом и дуплексом Сервис ... жаль, что нет VOIP-блога для обсуждения вопросов ...   -  person Big Dizzle    schedule 12.09.2013
comment
Я не хочу создавать экземпляр дуплексной службы внутри конструктора CallBackClient, но я хочу передать его конструктору (я хочу создать экземпляр дуплексной службы до создания экземпляра CallBackClient). Но, похоже, я не могу этого сделать из-за цикла зависимостей (InstanceContext- ›CallBackClient-› DuplexService- ›InstanceContext)   -  person Big Dizzle    schedule 12.09.2013
comment
Дуплекс, вероятно, не лучший вариант. Прочтите статью легенды WCF Джувала Лоуи: msdn.microsoft. ru / en-us / magazine / cc163537.aspx # S10   -  person tom redfern    schedule 12.09.2013


Ответы (1)


Вы можете попробовать это. win.service.Value - это время, когда Служба используется впервые, когда она будет создана (ссылка на оригинал с делегатом). Это также можно сделать с помощью метода SetService в Windows, разница в том, что кто-то может забыть вызвать его при создании экземпляра Windows. Все обязательные элементы должны быть в конструкторе Windows, то есть Контракт, Функция, а также Ленивая загрузка делает вашу Зависимость живой :)

Вам обязательно стоит провести рефакторинг вашего кода, попробуйте прочитать о принципах SOLID.

public class Service
{
    private int number;
    private Window win;

    public Service(int num, Window win)
    {
        number = num;
        this.win = win;
    }
}

public class Window
{
    public Lazy<Service> service;

    public Window(Func<Service> getService)
    {
        service = new Lazy<Service>(getService);
    }
}


    static void Main(string[] args)
    {
        Service  s = null;

        var win = new Window(() => s);

        s = new Service(1, win);

        Service winS = win.service.Value;
    }
person user007    schedule 12.09.2013
comment
Чувак, это на самом деле то, что я искал: Ленивая загрузка. Напишу решение позже для тех, кто столкнется с такой же проблемой. Я больше не задаю вопросов, Ваша честь. Дело закрыто. Пальцы вверх! - person Big Dizzle; 17.09.2013