I have a very simple wcf server. When a client uses an "operation" contract, I want to log this in a log file.
I came up with two solutions for this but I doubt they are good solutions and need some hints from the experts here.
My first solution:
instead of creating the host with typeof(serverclass), I use an instance of serverclass.
serverclass has an event and I attach an event handler to it that writes into the log.
The problem with this solution is it requires extra care with mult-threading, re-entrant, multi-session, per call settings ... etc.
My second solution:
use a static delegate inside serverclass and still create the host with typeof(serverclass). This way I can assign the logging function to the static delegate.
I don't feel this is the best way and I really appreciate comments or hints.
Thank you.
You may use WCF behaviour extensions to intercept the call and then write the log file.
There are various ways to intercept it by implementing various extension interfaces but message inspector is one of them.
Have a look here.
You could also consider an AOP approach. PostSharp is a good platform for this. The free version supports entry, exit, and error aspects.
Related
When capturing build events you can simply listen to the DTE2.Events.BuildEvents event. However is it possible to listen to these events without the use of DTE. I have read and heard from several people and sources that you should generally avoid using DTE, if somehow possible, due to its bad implementation or whatever.
In general if you're trying to automate Visual Studio you can either use DTE, which is the standard automation approach, or use native interfaces. The native interfaces start 'IVs...', e.g. IVsSolution. In both cases the technology is ancient and poorly-documented. As you suggest, a native solution does tend to be better.
Having said that, for the tasks running on a build that I've needed I ended up using DTE, which can be easier to program and made to work reliably.
I've found the equally-ancient articles (not the tools!) on the mztools.com website to be quite useful on this stuff, as well as the MSDN docs of course. Add 'mztools' to your Google search. For example, what mztools says on build events (Google 'mztools build events') is useful even though it dates from 2013.
I just want to share the code which actually works and achieves exactly what I needed. This was possible through the help of #Rich N, thanks for that one. It is actually easier than I thought, it is always the same procedure
Get the Svs... class from the GetService method and cast it to the corresponding interface.
Than append the Event Handler Class with the Advise... method.
// First of get the IVsSolutionBuildManager via the SVsSolutionBuildManager with the GetService method
var service = GetService(typeof(SVsSolutionBuildManager)) as IVsSolutionBuildManager;
// Appending the Events
service.AdviseUpdateSolutionEvents(new Events(), out var cookie)
// The class which handles the Event callbacks
public class Events : IVsUpdateSolutionEvents
{
// The implemented methods from the interface
}
I'd like to be able to add a couple of behaviors without having to call a method forcing them to be to used. A typical example is via an [InvokeErrorSupport] attribute whose purpose would be to fire off a test e-mail when deploying a service to ensure the error e-mails are coming through okay. Thus saving magic strings in a request Parameter Object, one or more non-business logic related [OperationContract] methods etc dirtying up the contract (with single responsibility in mind). We are more than happy to potentially invoke a method in other case such as our [Heartbeat] behavior and similar.
I have no problem writing the behaviors. It's a great feature of WCF but right now its looking like I'm going to have to add some method to the contract which I call such as Initialize which I'd lock down after start-up. Since, in this instance and more, the services are often external facing so we wish to avoid DoS attacks etc.
I've poked about client-side and can't see anyway and to be honest it kinda makes a degree of sense this functionality doesn't exist.
Can anybody offer any advice?
All of our services take a ServiceCallContext object as a parameter. The service then creates a broker and tells the broker what connection string to use based on the ServiceCallContext.
In other words, some of our customers have their own databases so the service calls have to point the brokers to their databases.
I would like to take the code that looks at the ServiceCallContext and chooses the correct connection and put it in a base service class. My team lead doesn't like that idea because with services he feels that this would be 'hiding' behavior and that this would be a bad thing. He suggested that there may be better ways to accomplish the same thing through some sort of WCF extensions.
I honestly don't care how we implement the code so long as I can reuse it because I think it's absolutely silly for me to be rewriting it in every service I create. I began looking into some WCF videos on PluralSight and it looks like there's a lot of great stuff it can do but unfortunately I'm not quite sure where to start. Can anyone give me a little direction as to whether WCF can accomplish what I'm trying to do and if so what particular features of WCF am I looking for?
The functionality you need is a custom interceptor.
This allows you to tell the WCF stack to look at incoming messages and the do some action based on them. If you wrap the interceptor up into it's own assembly then you can reference it from multiple services.
We have small lifetime scopes in our applications. It would be interesting to be able to intercept all services registered in autofac. By doing so we can see exactly which path the code takes for every lifetime scope and which method arguments are used. Not really usable for production but when really great for debugging/diagnostics/refactoring as you ge the whole picture and not just unit level.
But AFAIK it's only possible to register an interceptor for each single registration?
Nothing like this is supported out of the box with the Autofac.Extras.DynamicProxy2 library. You could potentially implement something like a module that handles OnActivating for every component using code similar to the stuff in Autofac.Extras.DynamicProxy2, but you'll run into trouble like...
Do you want class interceptors or interface interceptors? The type of service being resolved vs. the limit type of the component backing it will influence what kind of dynamic proxy you want to make. I believe the current A.E.D2 code only generates interception for either/or - not every interface a class implements, etc.
Do you use WCF client proxies? Client proxies are an interesting beast of their own so you have to special-case them. You'll see that in A.E.D2.
Generally problems like this get solved by aspect-oriented programming solutions (e.g., PostSharp) or profilers (e.g., ANTS)... or a combination of both. You might want to look into those solutions if you have the ability.
For an example of what sort of module implementation I'm talking about, check out the log4net integration page on the Autofac wiki. That shows how to handle OnPreparing for every component in the system. You can do the same thing, but handle OnActivating instead and use the sample on the Lifetime Events wiki page to show you how to swap one resolved thing for another (swap the real object for the generated proxy).
Context: I am hosting a number of services using WCF. I'd like for each of them to support a Ping operation (heartbeat, keep-alive, whatever...). But, I'd rather not go implement IPingable on each one. Instead, I'd love to do something like the serviceMetadata behavior does and dynamically add a channel dispatcher. This would mean all I'd need to do is add a pingable behvaior to the services and this operation is supported.
Any ideas? I've looked through the the source code of serviceMetadata and there is all kinds of internal stuff being called I don't have access to. Also, there may be an easier way.
Thanks for your time.
If you do it through a behavior, will your metadata indicate that the Ping operation exists?
Just off the top of my head could you add a dispatch behaviour that would handle the call and spoof the return true/false?
I also found the following