I have code as following:
Public Class xxxSvcHostFactory
Inherits ServiceHostFactory
Protected Overrides Function CreateServiceHost(ByVal serviceType As Type, ByVal baseAddresses As Uri()) As ServiceHost
Dim result As New WebServiceHost2(serviceType, True, baseAddresses)
Return result
End Function
End Class
Service contract is defined as below:
<ServiceContract()>
Public Interface IxxxSvc
<Description("")>
<OperationContract()>
<WebGet(ResponseFormat:=WebMessageFormat.Json,
UriTemplate:="CustomerDetails?id={CustomerId}")>
Function GetCustomerDetails(ByVal CustomerId As String) As Customer
End Interface
Public Class MySvc
Implements IxxxSvc
Public Function GetCustomerDetails(ByVal CustomerId As String) As Customer Implements IxxxSvc.GetCustomerDetails
.
.
.
End Function
End Class
When would CreateServiceHost gets executed?
Is it for every call, or for every transport session, or when the application startsup?
When does the ServiceHost expire?
If I implement static variable it is available through multiple sessions (say from IE and Firefox). How can I maintain static variable for a particular session (say if I access from IE, the same session should not be shared when I access from FF).
I am using WCF REST functionality in my application (core REST and not REST Starter kit).
thanks
It depends! :-) As always.....
If you host this service in IIS by using a MyService.svc file, then IIS will instantiate the WebServiceHost for each incoming request and spin up a service class instance to handle the request (ok, it's probably doing some caching on this - however, not quite clear how and how long the host will live etc.). IIS is said to have "message-based activation" - e.g. potentially each incoming message/request will activate the WebServiceHost.
When you self-host in a Windows NT Service, console app etc., it's obviously totally up to you - you create the WebServiceHost at your discretion, and then it's up and running until you explicitly tear it down (or an unhandled exception brings it down). Self-hosting gives you a bit more control over lifetime of your WebServiceHost.
Check out Hosting And Consuming WCF Services on MSDN - has lots of interesting info on hosting and lifetime of your service host and so forth.
Related
I have three projects, let's call them Client, Service and Execute.
Both Client and Service references Execute.
Client is a windows forms application. While first loading, it calls a shared method in a class called ParametersManager which fills four parameters in a class called Parameters.
Public Class Parameters
Public Shared Property FirstProperty As Integer
Public Shared Property SecondProperty As Integer
End Class
Public Class ParametersManager
Public Shared Sub FillParameters()
'In real scenario, I am just sending the parameters as arguments to the method.
Parameters.FirstProperty = 1
Parameters.SecondProperty = 2
End Sub
End Class
So when the application starts, it will call FillParameters from Execute.
I did debug the application, and when this method finish executing, the properties has the exact values that I gave them.
In one of the forms of the Client application, I am calling the Service which is an asmx Web Service. Service now calls a method from Execute project, let's call it UsePropertiesDoingSomething.
Public Class UseProperties
Public Shared Function UsePropertiesDoingSomething() as Integer
Return Parameters.FirstProperty + Parameters.SecondProperty
End Function
End Class
My problem is that when I call this function from the service, the properties are both equal to 0, not the values I have previously filled when the Client application first run.
How did I lose the the values? Shouldn't the values be saved in the Execute scope? How can I make sure not to lose them?
For testing purposes, I filled the parameters at the start of the Service, now when the Service calls the UseProperties the values are kept, but when called from the Client, the values are lost again.
For this purpose you have explore AppDomain and Execution context.
Shared does not means that it is shared between application or project. It is shared for specific application domain.
If same application domain load same library then it will be shared otherwise not as other application domain has it's own copy. (At least in .net it will not cross AppDomain boundry).
In your case Window Form has different Application Domain and ASMX in Web Service so it has different Application Domain so it will not be shared.
I have created my own WebService in VS 2010. My project is called sampleWebService and inside my project I have successfully added/connected to another WebService this is called practiceService.
sampleWebService has just the basic Hello World auto generated code in it, however, practiceService has Web Method Functions that handle database calls such as getFirstName, getLastName,...
My question isn't how to extract the data really since I know you have to use either JSON or SOAP. I'm just wondering what I have to type into my code to be able to see the functions and methods that are in my added web reference practiceService so I can connect to them.
Or maybe this is accomplished by using JSON or SOAP
Right now my code for my sampleWebService page is just as is:
<ToolboxItem(False)> _
Public Class Service1
Inherits System.Web.Services.WebService
<WebMethod()> _
Public Function HelloWorld() As String
Return "Hello World"
End Function
End Class
You can have a look at the proxy class that was generated when you added the web reference. Also when you create the object of practice service it will give you access to all the web methods exposed in that web service.
To access the web method you have to do something like
ServerName.WebServiceName CallWebService =
new ServerName.WebServiceName();
String sGetValue = CallWebService.MethodName();
Label1.Text = sGetValue;
Hopefully WCF has a reach instancing and concurrency management at service-side via Throttling.
My service client is an ASP.NET application. It consumes more than one WCF service so I create and parametrize WCF client at run-time (no configuration file is used).
Only the end point address is dynamic, and all the services (used by client) have the same method signatures (same contract).
For this reason I have referenced the service through Visual Studio and it has created my service proxy so I just take care of endpoint address at run-time:
class MyWcfClient
{
void DoSomething(string endpintAddress, int data)
{
// Create 'binding' and 'endpoint' ('endpoint' address is dynamic)
ServiceReference.ServiceClient serviceClient = new ServiceReference.ServiceClient(binding, endpoint);
// Parametrize 'serviceClient'
// Call WCF method (send 'data' to appropriate endpoint)
serviceClient.CLose();
}
}
Since the client is an asp.net application, each request runs on it's own worker thread (WCF method calls are very light and fast, so the thread would not block for a long time).
My question is about the instanciation and concurrency at the client-side.
Should MyWcfClient class be Singleton with one serviceClient instance or it be static class and a new serviceClient be created for each call ?
Should I create serviceClient (i.e, an array or list) based on the endpoints (there are 10-100 endpoints) ?
Note that my asp.net threads should not be blocked for a long time (i.e waiting in a queue for sending their related data via WCF)
There is no throttling on client side and it is not needed because you have client code under your control so you have control over number of requests executed. That is the difference to service where without throttling there is no control over number of incomming requests executed elsewhere (out of service control).
So if you want to control number of requests concurrently executed on client you must create object pool - there will be only limited number of MyWcfClient classes available and each class will always create new ServiceClient. Requests will wait in queue for free MyWcfClient instance.
If your only problem is how to create instances of ServiceClient then answer depends on type of binding.
Sessionful bindings like Net.Tcp, Net.Pipe or WsHttp with reliable session or security context: Create new instance for each communication relation. If your relation is just single call, create new instnace for each call. So you can use static class with static method and create new instance in that method.
Sessionless bindings like BasicHttp or WebHttp: You can reuse client for multiple calls but you can't close the client between subsequent calls. You can use array of prepared client instances. You will still need to handle some errors here.
Btw. also check asynchronous client calls and how to correctly close the service client.
There are a lot of article on this subject, but neither helped me. I am trying to implement service which could be used without "Add Service Ref..." mostly with advice from hhttp://www.netfxharmonics.com/2008/11/Understanding-WCF-Services-in-Silverlight-2 .
I made small project to reproduce problem.
http://hotfile.com/dl/96710945/9991ac3/SilverlightApplication8.zip.html
I tried solution like :
- Handling Faults in Silverlight
- Cross domain policy
etc
All standard checks are done like, service is active and reachable, client succeed to create channel etc.
I am stack whole week with this problem and I can not figure it out.
Every help is appreciate.
Denis,
try to create service in your web host project. Add service there and then you'll have a choice to add it as reference in your silverlight application. Just add a service in SilverlightApplication8.Web. Right click on SilverlightApplication8.Web --> Add new Item --> On left choose Silverlight --> Silverlight-enabled WCF service. And then add reference to your SilverlightApplication8.
I did not go in deeper investigation, but I assume that service implementation class type was not good.
So my factory class looked like:
Public Class TimeServiceFactory
Inherits System.ServiceModel.Activation.ServiceHostFactoryBase
Public Overrides Function CreateServiceHost(ByVal constructorString As String, ByVal baseAddresses() As System.Uri) As System.ServiceModel.ServiceHostBase
Dim host As New ServiceHost(constructorString, baseAddresses)
It needs to be changed in:
Public Class TimeServiceFactory
Inherits System.ServiceModel.Activation.ServiceHostFactoryBase
Public Overrides Function CreateServiceHost(ByVal constructorString As String, ByVal baseAddresses() As System.Uri) As System.ServiceModel.ServiceHostBase
Dim host As New ServiceHost(GetType(TimeService), baseAddresses)
Difference is I did not pass constructorString (which has information of type of service implementation class) , I passed GetType(TimeService) instate, which provided correct type information.
I am hosting a service within a Windows Service.
The following snippet instantiates the ServiceHost object:
Host = new ServiceHost(typeof(Services.DocumentInfoService));
The DocumentInfoService class implements a contract interface that has methods that invoke business objects requiring initialization (actually a connection string). Ideally, I'd like the hosting process to get the connection string from the config file and pass it to a constructor for my service object, DocumentInfoService, which would hold onto it and use it to pass to business objects as needed.
However, the ServiceHost constructor takes a System.Type object -- so instances of DocumentInfoService are created via the default constructor. I did note that there is another constructor method for ServiceHost that takes an object instance -- but the docs indicate that is for use with singletons.
Is there a way for me to get to my object after it is constructed so that I can pass it some initialization data?
ServiceHost will create the service instances based on the binding and behaviors configured for the endpoint. There's no particular point in time, where you can rely there is a service instance. Hence, ServiceHost does not expose the service instances.
What you could do is add code to your service object constructor to read the relevant configuration values itself through the ConfigurationManager class.
Of course, if you don't keep your configuration in the app.config, that won't work for you. Alternative approach would be to have a well-known singleton object that the service instances access when created to get the necessary configuration.
And there's also the option of creating your own ServiceHost or your own ServiceHostFactory to control the service instantiation explicitly. This would give you acess to the new service instances at the moment of creation. I would stay away from that option though. It's not worth the effort for your scenario.
Implement your own ServiceHost. See also http://hyperthink.net/blog/servicehostfactory-vs-servicehostfactorybase/