Friday, November 7, 2014

Suddenly - AOP, WCF, and Service Orientation

Suddenly all roads in my path of knowledge lead to AOP. It is all around me at the moment. Is it a tending topic in software or have I not been around the right circles until now?

Anyways, now to expand on my WCF topic of AOP that I introduced a couple posts ago.

After writing this, I felt compelled to add that this post is broad due to the recent extent of information processing this week. I apologize for being not more focused, but there were so many lessons learned and I feel I need to catch up since I've been neglecting this blog lately.

It's all cool that you can hook into the message processing pipe in WCF. That means you can intercept messages on the way in and out. You can access the headers, log the message, log details, log exceptions, and more. That's the same thing you get from the IoC way of doing this. So why should you host a bunch of services just to get AOP? It turns out that you don't have to host them separately.

WCF has the netNamedPipeBinding that uses binary serialization. It can be hosted in the same process as your consumer. So...if you have a your business logic divided into a few domains, you could put each in its own project that can be hosted in the same process as any workflow.

WCF has some built in logging at the message level and you can implement your own writers or use built in log writers. Or you can build up your own interceptors and do all the same pre-call, post-call, exception logging and auditing as you would with any class method.

The added benefit of using WCF in proc is that you can use the headers to share information and log that. If you do this, then you always have the option of switching to remote hosting to scale out. Perhaps one specific service has a long-running process and it needs to continue after the root application closes.

Consider a windows app that runs on a workstation in the intranet. The application has some process that eventually becomes a long-running process because the business rules changed. It needs to run async because of user experience. However, the user may fire-and-kill (pull the plug, end task, switch the power off), or the process becomes a resource issue, or the business logic changes more frequently so that it needs to be centralized for cleaner deployments (I'll consider the original design of not centralizing it poor in the first case, but this was the first example that came to mind).

In any case, we can now offload the process to a scalable server environment with just a few changes to the configuration settings. It's still in the internal network, only now its not local to the process or the machine. This implies at least three possible deployments, but there is at least one more and subclasses of that.

The service can live on the internet as well as the aforementioned inproc, on machine, or in network locations. If the service is over the net, it implies public accessibility. It could be hosted in the cloud or on a remote network. If it's on the net, in the cloud, you could tunnel to it and really take advantage of scalability.

I'm not making any strong recommendations here about where to host your services. These are just some of the available options. Consider what is appropriate. If you have an intranet and don't need to make your service publicly accessible, http in any case is not necessary and will only slow your communications down. InProc with net.pipe will offer the best communications performance. There's no reason you couldn't host the same service in more than one application, or even the same one.

Here's how the code looks to start the inproc service.

I was thinking about spinning hosts up in a web app, but this may be better to run as a windows service.

  • A host may spin up other hosts for it's dependencies. Can use IoC to create them. IMyService service = container.Get<IMyService>();
  • Perhaps consider disposal after it's not needed.
  • Let WCF handle threading, there are settings for that.
  • Can run as Task for calling async, but callbacks are possible so why not use those if desired, just don't dispose of the service before the callback.
  • Transactions can be coordinated across services via the DTC. Could be locking issues, so be careful to avoid deadlocks. Anyways, perhaps any transactions should be encapsulated in a service method if possible. The transaction could originate outside of the call or inside. using(var t = new Transaction()){ clientProxy.DoWork(); t.Commit();} Just need to make sure it flows into the service. Commits within the service for flowed transaction does not commit the trans, only votes yes. See DTC for more info (gtfy).
In this post, I provided an introduction to the possibilities of doing AOP in WCF along with reasons to host chunks of code in a service. I provided points about hosting the services in process when appropriate, as well as a few other points in general about WCF.

This information is not complete without mentioning the important consideration that this is a service oriented approach to programming and generally is more procedural in style. In contrast to object oriented programming which is more functional in style. While the services can be more or less OO inside, they generally should capture a specific unit of work. In some cases the unit of work is generic and in other cases it is very specific. The unit of work may be a composition of several services, or wholly encapsulated in one service. The services may be more generic and shared or very specific and not shared.

Now that the whole surface has been scratched, it should be clear to the reader that there are compelling reasons to use WCF and to understand service oriented programming as it evolves into its future form.

No comments:

Post a Comment