views:

1032

answers:

7

Hi,

Can you tell me what's the best way to send objects through NamedPipes in .net 3.5?

Thanks in advance

+2  A: 

Here's a helpful post. To send objects through streams, first read up about this here and here.

Vinay Sajip
I've read it but I need to send an object not text. I think I just don't know how to send object trough stream :(
kyrisu
+2  A: 

Use WCF on a NetNamedPipeBinding. See also Expose a WCF Service through a Named Pipes binding.

Remus Rusanu
+1  A: 

Serialize your object by XmlSerializer than send it as a text and deserialize in the other side, or use WCF named pipes binding as Remus suggests

ArsenMkrt
Why use XML Serialization if you're using WCF? Why not use the Data Contract Serializer, which will permit the object to be sent in binrary?
John Saunders
I suggest to use XmlSerializer if he doesn't want to use WCF, yea he can use Data Contract Serializer too
ArsenMkrt
+1  A: 

What you are looking for is DataContract attribute. See also: MSDN Using Data Contracts.

A data contract is a formal agreement between a service and a client that abstractly describes the data to be exchanged. That is, to communicate, the client and the service do not have to share the same types, only the same data contracts. A data contract precisely defines, for each parameter or return type, what data is serialized (turned into XML) to be exchanged.

Your service contract:

[ServiceContract]
public interface IApplicationRegistration
{
    // Sends the application information
    [OperationContract]
    bool RegisterApplication(AppInfo appInfo);
}

The data to exchange:

[DataContract]
public class AppInfo
{
    private int _processID;
    private string _processName;

    [DataMember]
    public int ProcessID
    {
        get { return _processID; }
        set { _processID = value; }
    }

    [DataMember]
    public string ProcessName
    {
        get { return _processName; }
        set { _processName= value; }
    }
}
Francis B.
+3  A: 

WCF NetNamedPipes binding is the way to go, you might also consider .NET Remoting to achieve this

Abhijeet Patel
+1  A: 

As a comment on the original question pointed out, you don't send objects to other processes. You can send data to another process, and that data can be used to create a proxy or facsimile of the original object in the other process, but you can't directly send an object.

Even technologies that offer inter-process object-passing semantics are, under the hood, doing exactly that. Because of this, you should always use the 'try to perform an operation, and catch the exception if it fails' style of operations rather than 'make sure it's okay to do the operation and then perform it' style. Even if the object looks like it's in a valid state for your operation, you're looking at old data, and so it may not be valid when you try to perform the actual operation.

So, since you can't send objects, what you're really going to end up doing is serializing some data (using XmlSerializer, or DataContractSerializer, or whatever), reading the data stream on the other end, and creating a new object to represent the old one. You may find it easier to create a separate object to represent the data you wish to send across the pipe, as opposed to the actual, live representation of the object.

WCF can handle a lot of this stuff automagically for you, but there's nothing too difficult about sending it over a pipe yourself.

If using WCF as others have suggested, be aware that you're still not sending "objects." You're still sending data, and WCF is pretty explicit about this (which is why they call it a DataContractSerializer, and not an ObjectSerializer). Specifically:

1) Any operations performed on an object sent with DataContract serialization will be performed locally.

2) If the same object is sent twice, it will not automatically update any old versions of it, and they will not have reference equality. You will have two data structures that, as far as C# is concerned, are entirely unrelated.

3) Updates to an object will only be performed locally, and will not automatically update other processes with the "same" object.

If you're absolutely convinced that you need to pass "objects" across processes, you can either roll your own (which I'd actually recommend, even though it's more work), or use the System.Remoting namespace.

Even if using System.Remoting, realize that what I've talked about above is what is actually happening, and design your objects and system with that in mind. You'll get a lot better results.

kyoryu
+1  A: 

Hi

Async named pipes here http://www.eggheadcafe.com/tutorials/aspnet/478ca475-2fd9-45d6-9090-5acdaeb00162/make-your-apps-talk-to-ea.aspx

uses some of my code ;-)

MaLio