Самостоятельно размещенный сервис WCF: как получить доступ к объекту (ам), реализующим контракт на обслуживание, из приложения хостинга?

Я самостоятельно размещаю службу WCF в клиенте WPF. Я хочу показать данные, которые служба получает в пользовательском интерфейсе. Каждый раз, когда поступают некоторые данные, пользовательский интерфейс должен обновляться.

Код в «App.xaml.cs» выглядит как

    private ServiceHost _host = new ServiceHost(typeof(MyService));

    private void Application_Startup(object sender, StartupEventArgs e)
    {
        _host.Open();
    }

    private void Application_Exit(object sender, ExitEventArgs e)
    {
        _host.Close();
    }

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


Спасибо всем за ответы.

Что я не видел, так это то, что конструктор ServiceHost позволяет передавать экземпляр сервиса вместо его типа .

Итак, что я делаю сейчас:

  • Используйте ObservableCollection в реализации сервиса
  • Настройте сервис как одиночный (см. Theburningmonk ' комментарий s)
  • Привязать к ObservableCollection в моем приложении WPF
  • Получить экземпляр службы, используя свойство привязки данных DataContext
  • Передать его конструктору ServiceHost

Результат: Каждое обновление в служба singleton WCF отражается в пользовательском интерфейсе.

Happy!

7
задан Robert 13 August 2010 в 12:48
поделиться

2 ответа

Как сказал marc_s, вы создаете WCF-сервис PerCall/PerSession, и новый экземпляр создается при каждом запросе/первом запросе каждой сессии.

Вы могли бы построить некоторую сантехнику вокруг этого так, чтобы экземпляр мог уведомить хозяина службы, когда он получает новый запрос, но это не будет легким упражнением, и вы должны помнить о потенциале для утечки памяти, если вы решите пойти с использованием событий, чтобы сделать это - без реализации паттерна Weak Event Pattern ваши экземпляры службы WCF могли бы остаться висящими вокруг, поскольку обработчики событий все еще держат ссылку на них, ЕСЛИ вы не забыли уведомить хозяина службы, чтобы отписаться, когда экземпляры службы WCF утилизируются.

Вместо этого, вот две идеи, которые могут облегчить вам достижение вашей цели:

Используйте Single InstanceContextMode, если ваша служба может быть сделана синглтоном, в этом случае вы создадите новый экземпляр, который реализует ваш контракт службы, и разместите его:

// instance will be your WCF service instance
private ServiceHost _host = new ServiceHost(instance); 

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

В качестве альтернативы, вы можете сделать все размещенные экземпляры фиктивными "fascades", которые разделяют статический класс, фактически обрабатывающий запросы:

[ServiceContract]
interface IMyService { ... }

interface IMyServiceFascade : IMyService { ... }

// dummy fascade
[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall]
public class MyServiceFascade : IMyServiceFascade 
{ 
    private static IMyService _serviceInstance = new MyService();

    public static IMyService ServiceInstance { get { return _serviceInstance; } }

    public int MyMethod()
    {
       return _serviceInstance.MyMethod();
    }
    ... 
}

// the logic class that does the work
public class MyService : IMyService { ... }

// then host the fascade
var host = new ServiceHost(typeof(MyServiceFascade));

// but you can still access the actual service class
var serviceInstance = MyServiceFascade.ServiceInstance;

Я бы сказал, что вам следует выбрать первый подход, если это возможно, это сделает жизнь немного проще!

13
ответ дан 6 December 2019 в 15:17
поделиться

Нет ни одного экземпляра объекта типа MyService, который был бы доступен - по умолчанию WCF использует модель per-call, например, для каждого входящего запроса будет создан новый экземпляр MyService, который будет использоваться для обработки этого запроса, а затем будет освобожден.

Таким образом, если нет хотя бы одного выполняющегося запроса, то, скорее всего, нет ни одного экземпляра сервиса.

Чего именно вы хотите добиться этим? Возможно, вам нужно пересмотреть свой подход и перейти от экземпляра класса сервиса - у него есть свойство .Host, которое ссылается на хост, на котором размещен этот конкретный экземпляр сервиса.

1
ответ дан 6 December 2019 в 15:17
поделиться
Другие вопросы по тегам:

Похожие вопросы: