I have a dependency injection container setup in my application and I'm thinking that composing the container every time a WCF service request comes in is going to be inefficient.
Can somebody explain to me, for an http/IIS hosted WCF service, what the lifecycle of the service is? If I can figure this out, I can make an educated decision on where the container is to be stored, instantiated, destroyed, etc.
If your InstanceContextMode is PerCall, the service class will be created from scratch for every incoming request, and then disposed of when it's done.
If your InstanceContextMode is PerSession, the service class will be created and used to service one given client for the duration of the session (or until an "InactivityTimeout" is encountered, or an error occurs).
If your InstanceContextMode is Single (singleton), the service class will be created when the first request comes in and will stay in memory as long as requests keep coming in, as long as no error occurs and no inactivityTimeout is reached.
So, there you have it! Of course, the concurrency mode (for PerSession and Single services) will also come into play to make things just a tad more "interesting"
As you mention that you were trying to integrate WCF service instantiation with a dependency injection container, I'd just like to say that I've had a very positive experience using the Castle WCF Integration Facility to do just that.
It's specific to the Castle Windsor dependency injection container but with it being open source you can look inside and understand some of the challenges and solutions provided.
It depends on your ServiceBehavour.
Specifically this and this.
Related
We are planning to redesign our services to micro services using service fabric, I have some questions that I hope you can help me with, here we go:
Communication Stack
All our services are on WCF using net.tcp so in theory we can reuse the WCF Communication stack but I'm not sure that's the best way, what are the differences between the default communication stack and the WCF one?
Extensibility
We have a lot of implementation using the extensibility points of WCF, if we choose the WCF communication stack can we still use this? We are basically using IServiceBehavior,IOperationInvoker, OperationContext and ServiceSecurityContext for this:
1. Security ServiceSecurityContext/OperationContext to get the IP and if the call is in the intranet the domain account who is making the call, I checked in StatelessServiceContext but could not find any property where i could get this info.
2. Parameters and time IOperationInvoker to log the parameters of the method and how much it took to finish the operation, reading this it appears that if implement the Start/Stop methods the time duration is done automatically, what I'm not sure is if this will work in the context of an attribute and with IErrorHandler when an error happens.
3. Notifications IErrorHandler to log the exception and then send an email to the developer team, we are currently doing this using an SMTP server, is there a better way to send notifications in azure?.
Thanks for your time
Answering this:
Communication Stack
Never did a comparison in performance between the default listener and WcfCommunicationListener but we opted for WCF to reuse all our components and as a first version to understand how service fabric works.
Extensibility
Security All the code worked the same, we needed to make some changes to the way the context works, but all the info needed was there (plus some data on the node it was running)
Parameters and time We used Azure Service Profiler with our own implementation of Microsoft.Diagnostics.Tracing.EventSource capturing the data using IOperationInvoker, awesome
Notifications IErrorHandler continued to work but we used sendgrid for the emails.
It is my understanding that a WCF service configured for net.msmq will not run as an HttpApplication when hosted in IIS/WAS, which means you don't get the events in Global (Application_Start being the important one). Am I correct in this regard?
Does using Windows Server AppFabric to auto-start the service hit the service over HTTP, causing the Application_Start event to fire? If so, is this reliable?
I guess my real question is, where is the "proper" place for initialization code for a non-HTTP WCF service?
Particularly (since the right place may be different for different stuff):
IoC registrations
log4net initialization
Verifying the MSMQ queue exists locally (as Juval Lowy suggests in his WCF book)
Follow-on question: Do the events in a custom IServiceBehavior fire on every request or only once at startup? What about ServiceHost.OnOpening() - every request or only once at startup? (My testing shows it's only once, but does anyone know where the WCF "lifecycle" is documented, because I can't seem to find it anywhere.)
I can't verify that WCF services hosted in IIS/WAS can't be configured to support Application_Start but it is not required to do what you want. I'd recommend you create a custom ServiceHost in conjunction with a custom ServiceHostFactory (for WAS). This approach is documented in an MSDN article and this blog post. Using this approach, you can host your service in IIS/WAS, a Windows Service or a console app because the initialization process will be the same.
We have a multi-system solution: several web sites and a separate App-Tier implemented / exposed as WCF services. The web sites all use EntLibs to log stuff - but they need to log to a central DB which is only accessible by the App-Tier.
To get around this we're looking at implementing a WCF service that can have LogEntires sent to it (via a Custom Trace Listener that sends the Log Entries to it).
The decision to use a WCF service is that it's in keeping with the rest of the architecture - and we don't have a lot of time to go doing much else.
I also looked at this and started wondering if we're on the wrong track altogether (from a performance perspective).
So, my question is:
Is this such a bad idea that I should just stop?
If it's viable, what are the traps I need to look out for?
The answer in the question you linked to covers it quite well, if you read between the lines:
Call the WCF logging service with "Is One way" = true, so that your client program does not wait for the logging to complete.
Set the WCF settings such that the client does not throttle the number of requests
I have been handed a wsdl file + a number of xsd type definition files - the service I need to code against is not ready yet and I need to put together a fake service (so called a stub or mock) in order to be ready when the real thing comes along.
My question is - once I get the interface I need to implement from the wsdl, how do I setup dependency injection so that whenever the new service comes along I can add a service reference or a web reference and just edit the spring.net config file to swap in the service I want in the consumer? Is it even possible?
I found this article, specific to WCF, It's pretty good but he seems to have access to the service code and he's doing dependency injection on the service side rather than on the consumer side - in my case I will most likely just get a url, I will have to swap it with the fake local one and go from there.
Also is there a way of doing this only dependent on the way I consume the service but not on the way the service was put together? I mean, I shouldn't care less which technology was used to develop the service as long as I get a url to the wsdl.
Any pointers appreciated!
Just create an interface which maps to the webservice methods and use that on the client side. It doesn't matter if it's a local service, webservice, or whatever.
I've done what you are trying to do before, you can read about it here.
While making my first ajax attempts, I decided also, to go to use IIS hosted WCF now. The strange thing is, that the WCF cannot process several requests parallel for the same user/session, if sessionmode is enabled! If sessionmode is disabled on asp.net, the requests are processed parallel. The broser/client may execute several different requests, where some of them are long running. This blocks all further requets and make my ajax app unusable.
This applies to asmx [webservices] also. I had a big hope, to compile the webservice methods using "IReadOnlySessionState" interface, but this has - in oppsite to webpages - no influence. But I need access [most times readonly] to the asp.net session!
Does someone knows any solution to this problems.
Anyway, thanks a lot!
br--mabra
In .NET 4, you can do this in Application_BeginRequest
if (Context.Request.Path.EndsWith("xxx.svc"))
Context.SetSessionStateBehavior(SessionStateBehavior.ReadOnly);
I found this:
http://blogs.msdn.com/silverlightws/archive/2009/09/30/having-a-pollingduplex-service-and-any-other-wcf-service-in-the-same-website-causes-silverlight-calls-to-be-slow.aspx
Which states,
"All WCF services require read/write session state access if you enable ASP.Net sessions, which causes the replies to be queued sequentially. Ideally user should be able configure the WCF handler to be read only, which would allow polling duplex services to work with sessions. Unfortunately this is unsupported at this point."
...the only thing I can think of is if there's some way to manually force early release of the lock. I'm looking into that now.
You can provide a custom session state provider
See: http://koolsand.blogspot.com/2010/02/why-iis-hosted-wcf-services-does-not.html
whenever a request contains svc in the
path it intimates default session
state provider to use readonly lock
and not read-write lock. So using
readonly lock will allow the next wcf
call to be executed concurrently.