David
David

Reputation: 73554

How can a self-hosted (WinForm ) WCF service interact with the main form?

Simplified version of what I'm trying to achieve:

I've got all of the above working just fine. I can step through the code and watch the flow of messages as the DisplayAlert() function is called.

What I can't figure out, and I can't believe it's so hard to find how to do something this simple:

- I'd like the DisplayAlert() function in the hosted service interact directly with the WinForm that's hosting it to make the form visible.

All I want to do is set the Visibility to true, and call another function on the WinForm.

This seems to me like it should be as simple as adding a reference to the form, or making a public function on the form and calling it from the service class, but I can't even figure out how to reference Form1 from within the service class.

Am I missing something obvious? How do I even reference the instance of Form1, which is hosting the service?

I've gone down the path of....

Any other suggestions?

I can add code if it helps.

Upvotes: 2

Views: 4877

Answers (3)

Beygi
Beygi

Reputation: 1953

Using this method you have completely a thread-safe application, and you don't have any limitation.

Service Contract Definition

[ServiceContract]
public interface IService
{
    [OperationContract]
    void DisplayAlert();
}

Service Implementation

public class Service:IService
{
    public void DisplayAlert()
    {
        var form = Form1.CurrentInstance;
        form.MySynchronizationContext.Send(_ => form.Show(), null);
    }
}

Program.cs

[STAThread]
static void Main()
{        
    var host = new ServiceHost(typeof (Service));
    host.Open();

    Application.SetCompatibleTextRenderingDefault(false);
    Application.EnableVisualStyles();
    Application.Run(new Form1());
 }

Form Implementation

public partial class Form1 : Form
{
    public static Form1 CurrentInstance;
    public SynchronizationContext MySynchronizationContext;
    private bool showForm = false;

    public Form1()
    {
        InitializeComponent();
        MySynchronizationContext = SynchronizationContext.Current;
        CurrentInstance = this;
    }

    // use this method for hiding and showing if you want this form invisible on start-up
    protected override void SetVisibleCore(bool value)
    {
        base.SetVisibleCore(showForm ? value : showForm);
    }

    public void Show()
    {
        showForm = true;
        Visible = true;   
    }

    public void Hide()
    {
        showForm = true;
        Visible = true;
    }
}

Client

class Program
{
    static void Main(string[] args)
    {
        Console.WriteLine("Press Enter to show form");
        Console.ReadLine();

        var client = new ServiceClient();
        client.DisplayAlert();
    }
}

Upvotes: 11

John Koerner
John Koerner

Reputation: 38079

Can you use a singleton for your service? If so you could implement it like this:

[ServiceContract]
[ServiceBehavior(InstanceContextMode=InstanceContextMode.Single)]
public class MyClass : IMyClass
{
    Form1 _f;
    public MyClass(Form1 f)
    {
        _f = f;
    }

    [OperationContract]
    public void Alert(string mess)
    {
        _f.Text = mess;
    }
}

Then when you setup your service host, you instantiate it and pass it the form:

MyClass c = new MyClass(this);
string baseAddress = "http://localhost:12345/Serv";
var host = new ServiceHost(c, new Uri(baseAddress));

Upvotes: 0

Mihai H
Mihai H

Reputation: 3291

In my opinion the answer is "simpol" as a friend says. First of all I would not even bother to follow the path described by you, after all a web service provides all the necessary means to communicate with it. Between your Form1 (which host your service) and your hosted service add a client (where client code is hosted by same Form1) and allow your client to communicate with your service using a duplex channel. In this way your client will know if a message was sent to your service by initiating a a long running request and being notified through the callback. Here is a link with a fancy article related to duplex channels: http://blogs.msdn.com/b/carlosfigueira/archive/2012/01/11/wcf-extensibility-transport-channels-duplex-channels.aspx

P.S: This is a rough suggestion to get you started which for sure can be improved.

Upvotes: 1

Related Questions