You can expose the service in two different endpoints.
the SOAP one can use the binding that support SOAP e.g. basicHttpBinding, the RESTful one can use the webHttpBinding. I assume your REST service will be in JSON, in that case, you need to configure the two endpoints with the following behaviour configuration
<endpointBehaviors>
<behavior name="jsonBehavior">
<enableWebScript/>
</behavior>
</endpointBehaviors>
An example of endpoint configuration in your scenario is
<services>
<service name="TestService">
<endpoint address="soap" binding="basicHttpBinding" contract="ITestService"/>
<endpoint address="json" binding="webHttpBinding" behaviorConfiguration="jsonBehavior" contract="ITestService"/>
</service>
</services>
so, the service will be available at
Apply [WebGet] to the operation contract to make it RESTful.
e.g.
public interface ITestService
{
[OperationContract]
[WebGet]
string HelloWorld(string text)
}
Note, if the REST service is not in JSON, parameters of the operations can not contain complex type.
Reply to the post for SOAP and RESTful POX(XML)
For plain old XML as return format, this is an example that would work both for SOAP and XML.
[ServiceContract(Namespace = "http://test")]
public interface ITestService
{
[OperationContract]
[WebGet(UriTemplate = "accounts/{id}")]
Account[] GetAccount(string id);
}
POX behavior for REST Plain Old XML
<behavior name="poxBehavior">
<webHttp/>
</behavior>
Endpoints
<services>
<service name="TestService">
<endpoint address="soap" binding="basicHttpBinding" contract="ITestService"/>
<endpoint address="xml" binding="webHttpBinding" behaviorConfiguration="poxBehavior" contract="ITestService"/>
</service>
</services>
Service will be available at
REST request
try it in browser,
http://www.example.com/xml/accounts/A123
SOAP request
client endpoint configuration for SOAP service after adding the service reference,
<client>
<endpoint address="http://www.example.com/soap" binding="basicHttpBinding"
contract="ITestService" name="BasicHttpBinding_ITestService" />
</client>
in C#
TestServiceClient client = new TestServiceClient();
client.GetAccount("A123");
Another way of doing it is to expose two different service contract and each one with specific configuration. This may generate some duplicates at code level, however at the end of the day, you want to make it working.
It is possible to create custom transports in WCF. It's quite involved though!
Roman Kiss has built a Null Transport that allows you to consume and host the services from within the same process without the overhead of marshalling the data through one of the built in transports. His CodePlex article is available at:
http://www.codeproject.com/KB/WCF/NullTransportForWCF.aspx
It may be a good starting point for helping you learn how to build your own transport. Good luck!
Best Solution
I put together a list of some resources for writing a WCF transport channels which might be useful. Not all links are still active, unfortunately, but most are and there's some useful stuff in there.
I also put a short introduction to how some of the pieces fit together which might help a bit.
Something I don't quite get in your question: You mention that you want to run the HttpBinding on top of your transport. Do you mean you want to use the WCF http transport channel on top of your custom socket-like API instead of the regular windows sockets API?
If so, then no, that won't work for various reasons. One of them is that the bindings and channels are not really that directly tied together, Instead the binding definition (i.e. which binding elements are included in it) controls how the channel stack is created at runtime for your service/client.
So basically, when writing your custom transport channel, you will create your own custom TransportBindingElement-derived class that you can use in a custom binding to use your own transport channel instead of one of the default ones (like HttpTransport). However, notice that a transport channel is, anyway, the bottom of the channel stack (i.e. there's nothing underneath it), so you can't layer the HttpTransport on top of your custom transport anyway (even if the API limitation was not there).
In other words, if you want to speak HTTP, you'll need to bake the HTTP stuff into your custom channel implementation. However, nothing prevents you from using the rest of the default basic/ws http bindings on top of your own channel, provided you expose the right channel shapes.