Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Self-hosted WCF service: How to access the object(s) implementing the service contract from the hosting application?

I am self-hosting a WCF service in a WPF client. I want to show the data the service receives in the user interface. Every time some data is received the user interface should be updated.

The code in "App.xaml.cs" looks like

    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();
    }

How can I get the object instance(s) implementing the service contract from the hosting WPF application?


Thanks everybody for the answers.

What I didn't see was that the constructor of ServiceHost allows to pass an instance of the service instead of its type.

So what I do now is:

  • Use an ObservableCollection in the service implementation
  • Configure the service to be a singleton (see theburningmonk's comment)
  • Bind to the ObservableCollection in my WPF application
  • Get an instance of the service using the databinding property DataContext
  • Pass it to the constructor of ServiceHost

Result: Every update in the singleton WCF service is reflected in the UI.

Happy!

like image 742
Robert Avatar asked Aug 12 '10 14:08

Robert


People also ask

How will you specify a method is available to access by client in WCF?

With the service running, right click the project that will contain the WCF client proxy and select Add > Service Reference. In the Add Service Reference Dialog, type in the URL to the service you want to call and click the Go button. The dialog will display a list of services available at the address you specify.

How do I host a WCF service in a managed application?

To host a service inside a managed application, embed the code for the service inside the managed application code, define an endpoint for the service either imperatively in code, declaratively through configuration, or using default endpoints, and then create an instance of ServiceHost.

What is self hosting in WCF?

This is referred to as a self hosting WCF service, the exact meaning of Self Hosted is that it hosts the service in an application that could be a Console Application or Windows Forms and so on. Earlier we saw what a WCF Service is in the . Net environment. We can host a WCF service in IIS and a Windows service also.


1 Answers

As marc_s said, you're creating a PerCall/PerSession WCF service and a new instance is created on every request/first request of every session.

You could build some plumbing around it so that the instance can notify the service host when it receives a new request but it won't be an easy exercise and you need to be mindful of the potential for memory leak if you decide to go with using events to do this - without implementing the Weak Event Pattern your WCF service instances could be left hanging around as the event handlers still holds a reference to them UNLESS you remember to notify the host to unsubscribe when the WCF service instances are disposed.

Instead, here's two ideas which might make it easier for you to achieve your goal:

Use the Single InstanceContextMode if your service can be made a singleton, in which case you will create a new instance which implements your service contract and host it:

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

that way you will have access to the instance that will retrieve the client requests.

Alternatively, you could have all the hosted instances be dummy 'fascades' which share a static class that actually process the requests:

[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;

I'd say you should go with the first approach if possible, makes life that bit easier!

like image 120
theburningmonk Avatar answered Sep 30 '22 12:09

theburningmonk