Find Endpoint addresses for a service implementation without OperationContext.Current - wcf

I have a WCF service in which I would like to do some initialization-type operations based on the configured EndpointAddresses for a few different contracts implemented by the service.
The service can be (and is) hosted from within a few different Service Hosts. There is a console application which creates a service host, a windows service which creates a service host, it lives in an IIS host and I would also really like to be able to use the Visual Studio service host for debugging.
Is there any way to get a reference to the ServiceHostBase which created the instance of the service without being inside a service operation? Or maybe a better (read: trickier) way of figuring out what endpoints the service is servicing?

Let me see if I have this straight: You have a single Service implementation that is exposed from multiple ServiceHosts, and you want to do some different initialization for each servicehost? Or is it for each endpoint exposed?
It sounds to me like there are a few options here, but it depends on exactly what you want to do. If the intialization is per-host, then why not just use your own ServiceHost implementation and do the initialization there instead of the service?.
I ask this particularly because it is not clear from your description what the instance mode of your service is or when you want to run the initialization code itself.
If for whatever reason you can't do that, another option worth exploring could be to do the initialization in a custom IServiceBehavior during ApplyDispatchBehavior(), where you've got access to the service host and the service description.

Related

Should I Open and Close my WCF client after each service call?

I have developed a WCF service for consumption within the organization's Ethernet.
The service is currently hosted on a windows-service and is using net.tcp binding.
There are 2 operation contracts defined in the service.
The client connecting to this service is a long running windows desktop application.
Employees(>30,000) usually have this client running throughout the week from Monday morning to Friday evening straight.
During this lifetime there might be a number of calls to the wcf service in question depending on a certain user action on the main desktop client.
Let us just say 1 in every 3 actions on the main desktop application would
trigger a call to our service.
Now we are planning to deploy this window service on each employee's desktop
I am also using `autofac` as the dependency resolver container.
My WCF service instance context is `PerSession`, but ideally speaking we have both the client and service running in the same desktop (for now) so I am planning to inject the same service instance for each new session using `autofac` container.
Now am not changing the `InstanceContext` attribute on the service implementation
because in future I might deploy the same service in a different hosting environment where I would like to have a new service object instance for each session.
Like mentioned earlier the client is a long running desktop application and I have read that it is a good practise to `Open` and `Close` the proxy for each call but if I leave the service to be PerSession it will create a new service instance for each call, which might not be required given the service and client have a 1-1 mapping. Another argument is that I am planning to inject the same instance for each session in this environment, so Open & Close for each service call shouldn't matter ?
So which approach should I take, make the service `Singleton` and Open Close for each call or
Open the client-side proxy when the desktop application loads/first service call and then Close it only when the desktop application is closed ?
My WCF service instance context is PerSession, but ideally speaking we have both the client and service running in the same desktop (for now) so I am planning to inject the same service instance for each new session using autofac container
Generally you want to avoid sharing a WCF client proxy because if it faults it becomes difficult to push (or in your case reinject) a new WCF to those parts of the code sharing the proxy. It is better to create a proxy per actor.
Now am not changing the InstanceContext attribute on the service implementation because in future I might deploy the same service in a different hosting environment where I would like to have a new service object instance for each session
I think there may be some confusion here. The InstanceContext.PerSession means that a server instance is created per WCF client proxy. That means one service instance each time you new MyClientProxy() even if you share it with 10 other objects being injected with the proxy singleton. This is irrespective of how you host it.
Like mentioned earlier the client is a long running desktop application and I have read that it is a good practise to Open and Close the proxy for each call
Incorrect. For a PerSession service that is very expensive. There is measurable cost in establishing the link to the service not to mention the overhead of creating the factories. PerSession services are per-session for a reason, it implies that the service is to maintain state between calls. For example in my PerSession services, I like to establish an expensive DB connection in the constructor that can then be utilised very quickly in later service calls. Opening/closing in this example essentially means that a new service instance is created together with a new DB connection. Slow!
Plus sharing a client proxy that is injected elsewhere sort of defeats the purpose of an injected proxy anyway. Not to mention closing it in one thread will cause a potential fault in another thread. Again note that I dislike the idea of shared proxies.
Another argument is that I am planning to inject the same instance for each session in this environment, so Open & Close for each service call shouldn't matter ?
Yes, like I said if you are going to inject then you should not call open/close. Then again you should not share in a multi-threaded environment.
So which approach should I take
Follow these guidelines
Singleton? PerCall? PerSession? That entirely depends on the nature of your service. Does it share state between method calls? Make it PerSession otherwise you could use PerCall. Don't want to create a new service instance more than once and you want to optionally share globals/singletons between method calls? Make it a Singleton
Rather than inject a shared concrete instance of the WCF client proxy, instead inject a mechanism (a factory) that when called allows each recipient to create their own WCF client proxy when required.
Do not call open/close after each call, that will hurt performance regardless of service instance mode. Even if your service is essentially compute only, repeated open/close for each method call on a Singleton service is still slow due to the start-up costs of the client proxy
Dispose the client proxy ASAP when no longer required. PerSession service instances remain on the server eating up valuable resources throughout the lifetime of the client proxy or until timeout (whichever occurs sooner).
If your service is localmachine, then you consider the NetNamedPipeBinding for it runs in Kernel mode; does not use the Network Redirector and is faster than TCP. Later when you deploy a remote service, add the TCP binding
I recommend this awesome WCF tome

WCF central service with multiple clients

i can't find any good architecture explanation of how can WCF SHOULD be part of a main-server with multiple clients.
in my solution, i want to have a central WCF service (hosted in windows-service on windows server machine).
The central service is the only one that's connected to the DB.
all the clients, are connecting to this main service, login, and get having a duplex communication.
via that main service, one client can connect another one. or when one client using the main service to change the DB, the main service updates all other clients.
for doing that, i added in the main service the InstanceContextMode.Single attribute, and in the windows-service, i init ServiceHost with the WCF-service singleton.
it works. so so..
i can continue and search where the problems are, and how to fix them, but it looks like something here is not right, like i'm not supposed to do it this way.
i could really use an advice on how WCF service should be used as a main service with multiple clients, that require common memory.
it's basically for ~20 clients with not too intensive operations, but i still want the option to let them all communicate simultaneously with the main service, and not only one by one.

WCF constructor Service Type via DI

I'm currently trying to build a small App-Server which shall host multiple WCF services. These services (and their dependencies of course) should be instantiated by an DI/IoC Container (currently LightCore but since I am using it via the CommonServiceLocator it should be easy to exchange).
Unfortunately I stumbled onto a problem. Obviously I have to create ServiceHost instances to host mentioned WCF services. I already built a customized InstanceProvider and ServiceBehavior to handle all dependencies of the services, BUT the Constructor of ServiceHost needs the Service Type of the service to host. At this point in my program, I only know the Interface Type, since only the DI container knows which Service implementation is currently being used.
A cheap method would be to create a "dummy" instance of the service type via Service Locator and give the ServiceHost constructor the output of myDummyInstance.GetType(), but that just hurts to look at, useless instantiation and usage of Service Locator instead of DI...there has to be a better way.
Any ideas anyone? :)
There are multiple ways how to do that.
The way I like is very simple. You will not resolve contract of your service but service implementation itself because simply that is what WCF expects. All IoC containers I used are able to resolve type itself and fill its dependencies.
Another way is little bit more hack. When you call the constructor of service host you will resolve type of the service contract by call like ServiceLocator.Resolve<IContract>().GetType(). It is ugly but it is much more clean then creating dummy implementations. Moreover you never know if the passed type is not used for something else in the infrastructure so passing dummy type can be dangerous.

Any recommendations to host a WCF service?

Have a winform application and want to host a WCF service inside it. Do I need to host it in a seperate appdomain? Any recommendations?
You don't need to host it in separate domain but you must decide if you want service request to be processed by UI thread or different thread. It depends on the way you create ServiceHost instance or on ServiceBehavior applied to your service class.
When service is hosted in UI thread it can directly interact with UI but request processing is part of message loop and all service requests are processed by single thread (sequentially). When request is processed no other windows event (including UI events) can be processed = application freezes.
When service is hosted in different thread it behaves as in any other hosting environment but it can't directly interact with UI - you must use delegate invocation.
Ways to enforce service to run in own threads:
Create and open ServiceHost instance before you call Application.Run (start of Windows message loop)
Create and open ServiceHost instance in separate thread
Use [ServiceBehavior(UseSynchronizationContext = false)] on your service implementation
No, you don't have to host it in a separate AppDomain. Just host it. There's nothing terribly special about WinForms in this regard.
What's your app do? Is the service a part of the apps regular functions or a completly seperate logical entity?
If you want to be loading and unload resources (such as assemblies) related to your service without shutting your app down a seperate app domain would make this much easier, but otherwise I don't see much of a reason to complicate things.
Just my 2c. :-)
You can host in Win form but you have to keep it running throughout.
Also suggest you to host in IIS so any type of client avail your service.

Self hosted WCF ServiceHost/WebServiceHost Concurrency/Peformance Design Options (.NET 3.5)

So I'll be providing a few functions via a self hosted (in a WindowsService) WebServiceHost (not sure how to process HTTP GET/POST with ServiceHost), one of which may be called a large amount of the time. This function will also rely on a connection in the appdomain (hosted by the WindowsService so it can stay alive over multiple requests).
I have the following concerns and would be oh so thankful for any input/thoughts/comments:
Concurrent access - how does the WebServiceHost handle a bunch of concurrent requests. Are they queued and processes sequentially or are new instances of the contracts automagically created?
WebServiceHost -> WindowsService communication - I need some form of communication from the WebServiceHost to the hosting WindowsService for things like requesting a new session if one does not exist. Perhaps implementing a class which extends the WebServiceHost with events which the WindowsService subscribes to... (unless there is another way I can set off an event in the WindowsService when a request is made...)
Multiple WebServiceHosts or Contracts - Would it give any real performance gain to be running multiple WebServiceHost instances in different threads (one per endpoint perhaps?) - A better understanding of the first point would probably help here.
WSDL - I'm not sure why (probably just need to do more reading), but I'm not sure how to get the WebServiceHost base endpoint to respond with a WDSL document describing the available contract. Not required as all the operations will be done via GET requests which will not likely change, but it would be nice to have...
That's about it for the moment ;) I've been reading a lot on WCF and wish I'd gotten into it long ago, but definitely still learning.
Concurrent access - this is something you can set using ServiceBehaviorAttribute. there are a number of options -- you can have WCF create a new instance of your service class for each incoming request, or you can have a single instance handle all requests. Additionally you can tell WCF whether to pass you the requests serially or concurrently.
WebServiceHost -> WindowsService communication. Two approaches spring to mind: WCF supports a mode called "well known instance" where you pass an instance of your service to the ServiceHost constructor instead of passing a Type and letting WCF instantiate it for you. With this mode you can preconfigure your service instance with a reference back to your hosting code (alternatively you could use events). An alternative if you want to preserve instancing flexibility would be to have a static method in your hosting code that the WCF service could call back into.
Multiple WebServiceHosts or Contracts - really no advantage to having more than one ServiceHost instance. see also this SO thread: What are the benefits for several servicehosts? Does one ServiceHost support several simultaneous connections on one endpoint?.
WSDL - While you can enable WSDL by turning on metadata publishing (http://msdn.microsoft.com/en-us/library/ms788760.aspx), WSDL support is intended for SOAP-based services, not pure HTTP GET/POST. The WSDL that gets auto-generated for your service will likely not be very useful.