Creating asynchronous WCF clients without using Service References - c#

Currently I do not use Service References as I feel the code it autogenerates is more weight than I need. Instead I generate a proxy class by doing:
public class MyClient : ClientBase<IMyService>, IMyService
This has worked great for me, no proxy classes are generated so I reuse the same datatypes. But this only lets me create synchronous client methods.
What would it take to generate async versions? I have taken a look at the autogenerated code that adding a Service Reference would do and it seems like soo much boilerplate. A ton of begin/end/onbegin/oncomplete associated event arg datatypes etc etc.
Is there a simpler way with less scaffolding needed to create async client methods?
My ultimate end goal is to be able to use the new c# 5 async/await keywords on webservice clients

You can always author a contract IMyAsyncService that is exactly like IMyService but uses the Begin/End async pattern (and has [ServiceContract(Name="IMyService")] to keep the same name). It will be the same wire contract, and work with ClientBase, but now you have async methods you can use with await.

I think adding this
[OperationContract(IsOneWay = true)]
to your method declaration in the Interface on your services will determine its async.

The CTP for async/await is just a preview of the support for these features. They plan to fully integrate them into WCF.
http://blogs.msdn.com/b/endpoint/archive/2010/11/13/simplified-asynchronous-programming-model-in-wcf-with-async-await.aspx

Related

ASP.NET Web API: any downsides to asynchronous operations?

I'm setting up a Web API that will serve a client over our Intranet. For the sake of convenience for the developers working on the client, I am considering having the Web API adhere to an interface that will be shared with the client, something like what is shown below.
The purpose of using a shared interface mostly has to do with making changes to the Web API detectable by the client developers at compile time. Also, the client can leverage the interface to be used for wrappers around HttpClient instances that will be used to communicate with the Web API.
The client developers would like to use async and await throughout their implementation, and who am I to say "no"?
public interface IValueController
{
Task<string> ReadAsync();
string ReadSync();
}
[Route("api/v1/[controller]")]
public class ValueController : Controller, IValueController
{
[HttpGet("async")]
public Task<string> ReadAsync()
{
return Task.FromResult("async!");
}
[HttpGet("sync")]
public string ReadSync()
{
return "sync!";
}
}
I'm not all that interested in providing both synchronous and asynchronous methods - one of them will have to do. The question is: Is there any down-side to defining the Web API operations as asynchronous? If not, I'm going all-in!
-S
When to use Async:
Async API calls.
Long Running database queries.
Tasks that are CPU bound.
When you need to achieve parallelism.
When not to use: While writing any quick running tasks or methods.
NOTE: Beware of deadlocks as the compiler allows you to write and successfully compile async code even without understanding it's basic concept.
The purpose of using a shared interface mostly has to do with making changes to the Web API detectable by the client developers at compile time.
These days, it's more common to auto-generate an API description (e.g., Swagger), and then auto-generate clients from that (which can be .NET or other languages). Not only does this approach allow multiple clients (e.g., one Swagger client is HTML documentation for your APIs, complete with examples and the ability to invoke them right from the website), but it also handles the synchronous/asynchronous translation for you without requiring any kind of "async signature but really it's sync" code.
That said, if you wanted to implement asynchronous methods synchronously, there's nothing that would prevent it. The only gotcha I can think of is that if you're on full ASP.NET, then asynchronous actions cannot be child actions. This restriction no longer exists on ASP.NET Core.

Possible to consume a WCF service in Silverlight via a channel factory, using a Portable Class Library?

The Current Setup: Silverlight client consuming regular WCF services using RIA classes and generated service references.
The Goal: Replace the service references and RIA classes with channel factories and a Portable Class Library (PCL). (XY goal: get rid of generated code.)
The Approach So Far:
The first part of this -- using channel factories -- is straightforward, and well documented. Basically, the WCF service remains as-is, with the caveat that the ServiceContract has to be defined on an interface. Then on the client you create a ChannelFactory<IMyService>, supply the service URL, and the proxy is created like magic (no need for a service reference).
There is a wrinkle with Silverlight, namely that you have to use conditional compilation to define asynchronous operation contracts. (This will be important in a moment when I try to move the operation contract to the PCL.) Thus the service contract will look something like this:
[ServiceContract]
public interface IMyService
{
#if SILVERLIGHT
[OperationContract(AsyncPattern = true)]
IAsyncResult BeginGetAString(AsyncCallback callback, object state);
string EndGetAString(IAsyncResult result);
#else
[OperationContract]
string GetAString();
#endif
}
Note that it is (apparently) necessary to exclude the synchronous operation from the Silverlight compilation, as above. Otherwise, the call to ChannelFactory.CreateChannel complains:
The contract 'IMyService' contains synchronous operations, which are not supported in Silverlight. Split the operations into "Begin" and "End" parts and set the AsyncPattern property on the OperationContractAttribute to 'true'. Note that you do not have to make the same change on the server.
So far so good. The next step is to move code that is shared between client and server, from RIA .shared class files to a PCL. For the DataContract classes, this works perfectly well -- but trying to move the OperationContract class presents a problem. The Silverlight ChannelFactory approach requires the conditional compilation of the synchronous method definition, as above, which (as is my understanding) is not possible in a PCL.
The Question:
What is the most straightforward way (if any) to get this to work, short of abandoning the channel factory approach or maintaining an RIA project? For example, is there any way to tell Silverlight to simply ignore synchronous operations, rather than throwing an error? Or any way to somehow exclude the synchronous definition for the Silverlight-targeted PCL (eg, a conditional build maybe)?

What's the best design pattern for this?

I have a requirement to add a layer between an external library and client code, such that the client has a consistent interface to the underlying library and we are able to switch out the library with the minimum of code changes.
For example:
public interface IConsistentInterface
{
void Foo(string bar);
void Bar(string foo);
}
Internally the concrete implementation of this interface will be calling into the library, using whatever functionality that offers. This way if we switch out the library, we just need to change the internal calls of concrete types of this interface.
This looks to me like the Adapter pattern, but is this the best approach to the problem?
Thanks.
It seems like the Gateway pattern might fit nicely here. However, as you say, the Adapter pattern can also work well for you. In fact, thinking about it there seems little difference between how the two might look in code.
You can't go wrong normalising the external API into another API your code can consume consistently. If changes occur in the external API, the breaking code will be limited to your normalised API, where you can either do a fix or damage limitation. The net effect, and the one both patterns aim for, is a much reduced surface area of impact on the rest of your code.

Upcasting ServiceContract

I have a WCF service, which exposes many methods.
My application consumes this service, and ServiceContract includes OperationContract definitions for only some of methods.
To cut to the question, consider following code example:
[ServiceContract]
public interface IServer
{
[OperationContract]
void BasicOperation();
}
[ServiceContract]
public interface IExtendedServer : IServer
{
[OperationContract]
void ExtendedOperation();
}
I would like to make contracts so that application has extension capability. In other words, I'd like to be able to use IServer contract everywhere, but to allow plugin-like architecture to extend basic contract interface, so that plugin itself can call ExtendedOperation() operation contract.
So, how do I structure my code, or, what changes do I have to make, in order to be able to do something like following? (channel is of type IServer)
((IExtendedServer)channel).ExtendedOperation()
When I attempt to do this, I get error
System.InvalidCastException : Unable to cast transparent proxy to type 'Contract.IExtendedServer'.
I hope I wasn't confusing...
Services in a SOA world need to have a well-defined and pretty static interface. SOAP services require a representation in a WSDL (and included or separate XSD = XML schema for the data involved).
I don't see how you can create something like a plug-in system in a service world. Plugins work great on a local app - load your resources, language extensions, graphics filters - whatever strikes your fancy. But in a SOA world, this "agility" is the exact contrary of what you're trying to do - create and offer well-defined, fully specified services to be used.
The only option I could see is using a REST-based approach, since there you don't really have many of those limitations. Normally I say this lack of a formal service description is one of the major drawbacks and weak points of REST, but since using REST, the operations are really just defined by the URL's used, this might be a plus in your case.
So I would say: if you really want flexibility in services, you need to check out REST based services. SOAP doesn't fit that bill. Go to the WCF REST Developer Center on MSDN for a vast array of information and resources on how to use REST in and with WCF.
I'm not sure what you're trying to accomplish here. You're dealing with services, which have endpoints exposing specific contracts (i.e. interfaces). You're not dealing with objects and casting and the like; it won't work and isn't the right approach anyway.
The way I see it, what you have is indeed just that: A service that exposes one endpoint with a set of common operations, and potentially X number of additional endpoints with other contracts with extension operations. You could still have a single service class on the service side, but as far as the client goes, they are simply different endpoint/services.

Request for advice about class design, inheritance/aggregation

I have started writing my own WebDAV server class in .NET, and the first class I'm starting with is a WebDAVListener class, modelled after how the HttpListener class works.
Since I don't want to reimplement the core http protocol handling, I will use HttpListener for all its worth, and thus I have a question.
What would the suggested way be to handle this:
Implement all the methods and properties found inside HttpListener, just changing the class types where it matters (ie. the GetContext + EndGetContext methods would return a different class for WebDAV contexts), and storing and using a HttpListener object internally
Construct WebDAVListener by passing it a HttpListener class to use?
Create a wrapper for HttpListener with an interface, and constrct WebDAVListener by passing it an object implementing this interface?
If going the route of passing a HttpListener (disguised or otherwise) to the WebDAVListener, would you expose the underlying listener object through a property, or would you expect the program that used the class to keep a reference to the underlying HttpListener?
Also, in this case, would you expose some of the methods of HttpListener through the WebDAVListener, like Start and Stop, or would you again expect the program that used it to keep the HttpListener reference around for all those things?
My initial reaction tells me that I want a combination. For one thing, I would like my WebDAVListener class to look like a complete implementation, hiding the fact that there is a HttpListener object beneath it.
On the other hand, I would like to build unit-tests without actually spinning up a networked server, so some kind of mocking ability would be nice to have as well, which suggests I would like the interface-wrapper way.
One way I could solve this would be this:
public WebDAVListener()
: WebDAVListener(new HttpListenerWrapper())
{
}
public WebDAVListener(IHttpListenerWrapper listener)
{
}
And then I would implement all the methods of HttpListener (at least all those that makes sense) in my own class, by mostly just chaining the call to the underlying HttpListener object.
What do you think?
Final question: If I go the way of the interface, assuming the interface maps 1-to-1 onto the HttpListener class, and written just to add support for mocking, is such an interface called a wrapper or an adapter?
I'll answer your last question first: a class is an adapter if it implements some ITarget interface using a contained object matching some ISource -- an adapter from ISource to ITarget. In this case, there is no source interface, you're trying to add one in, so I'd call it a wrapper.
I'd be inclined to
Make a WebDavListener class which has all the methods it needs for its own behaviour, uses an HttpListener internally, and doesn't expose anything about that HttpListener.
If and when you need it, make IHttpListenerWrapper and HttpListenerWrapper as you suggest, and change the WebDavListener to take an IHttpListenerWrapper in its constructor. Assuming all the methods are the same, this should be a simple search-and-replace. You could even leave the original constructor in there and have it construct a wrapper and call the new constructor.
If and when you need it, make an IWebDavListener for it to implement, if you think you might want a dummy WebDAV listener for unit testing other things.
This sort of design issue is why I love refactoring tools like ReSharper: Extract Interface, Create Derived Implementation etc. make it much easier to make these sort of changes, so you can worry less about whether to do them now or later :-) (Assuming you are allowed to freely change the source later, of course, which depends how you're delivering things.)

Categories

Resources