I'm trying to make a simple scheduler service that will automatically send emails, etc.
For now I have simple WCF service in which I create an instance of a timer, set a callback and do some work in the callback. Now this part works fine, with the callback being called and the work in it being done as expected.
The issue is I need to make some change to the timer, say change the interval or maybe just stop it.
But I can't seem to figure out a way to store/get the instance of that timer that I created. As each time I create a new proxy and access the service, I get a new instance of the service...
I know I could use a static variable but that kind of makes it a 'singleton' service, and the service host I am using at the current time does not support that...
So how can I get that instance of a timer/thread that I actually created in a previous call? Or am I just going about this the wrong way?
Static isn't all that bad of an idea here. Maybe that static is a dictionary keyed by a Guid and the Guid is returned to the client. Subsequent client calls use the Guid parameter, so new instances of your service lookup the timer using the Guid.
Related
I read some articles about this and I get to know how to use Transient, Scoped, and Singleton but I am confused when to use one of these.
What I am understood:
Singleton: In situation when you need to store number of employees then you can create singleton cause every time you create new employee then it will increment the number so in that situation you need singleton.
Scoped: For example you are playing game in which number of life is 5 and then you need to decrease the number when player's game over. And in every new time you need new instance because every new time you need number of life is 5.
Transient: when to use Transient??
Please correct me if I am wrong.
And give the better example of all of them if possible.
As far as I know, the Singleton is normally used for a global single instance. For example, you will have an image store service you could have a service to load images from a given location and keeps them in memory for future use.
A scoped lifetime indicates that services are created once per client request. Normally we will use this for sql connection. It means it will create and dispose the sql connection per request.
A transient lifetime services are created each time they're requested from the service container. For example, during one request you use httpclient service to call other web api request multiple times, but the web api endpoint is different. At that time you will register the httpclient service as transient. That means each time when you call the httpclient service it will create a new httpclient to send the request not used the same one .
Note, Microsoft provides the recommendations here and here.
When designing services for dependency injection:
Avoid stateful, static classes and members. Avoid creating global state by designing apps to use singleton services instead.
Avoid direct instantiation of dependent classes within services. Direct instantiation couples the code to a particular implementation.
Make services small, well-factored, and easily tested.
Now I need to reference a WCF service in a UWP program. However, the address of the WCF service may change frequently in the future.
I don't want to rebuild/republish the project every time when the address change.
So I want to use a LocalSettings to Save/Load the address of WCF service. Every the program begins, it will reload the address from the LocalSettings. And if the address changes, I just only let the customer change the LocalSettings from UI but not need to rebuild/republish the project.
How can I do it? Or there is any other better to do it?
If it's a RESTful service, you could use HttpClient relevant APIs to consume a REST service in UWP.
Please note that REST is a resource that implements a uniform interface using standard HTTP GET, POST, PUT methods that can be located by URI. So, you could use HttpClient to call it in code-behind. You will get response after you send http request, then you could analysis the response result.
The similar thread for your reference: Calling web service asynchronously in page constructor.
Using LocalSettings for such thing is a good solution.
LocalSettings are just a dictionary where you can assign values you want to store and later take out.
ApplicationData.Current.LocalSettings["ServiceAddress"] = "something";
Debug.WriteLine(ApplicationData.Current.LocalSettings["ServiceAddress"]);
Such setting will survive app restart and is stored in applicaton's private storage.
You will probably want to seed this setting with a default value at first startup.
I have a WCF service which need to initialize some expensive resources used for all incoming calls. Firstly I used a static variable to record its status, but the variable was reset on every call. Then I used a static service constuctor to init, but it got called on every incoming call. I tried to set InstanceContextMode to Single and PerSession, but neither of them worked.
Any ideas?
Setting your InstanceContextMode to Single is definitely the way to go if you need access to these resources across ALL calls to the service. What probably happened (just a guess) is your worker process is getting recycled, resulting in your initialization code have to run again when a new worker process is started. If that is what is happening, then take a look at this document to configure your application pool to use auto-start.
http://msdn.microsoft.com/en-us/library/ee677260.aspx
If this doesn't help then some additional details on how/where your initialization code is implemented would be helpful.
I have a web service that will be consumed by some application (web site currently).
The calls are almost all specific to a certain client but still the same. So one call might be getAllFoo() but I would need some parameter to say from which client the Foo is.
It would become bothersome quickly if I just add a standard parameter to all calls so I was hoping to do it a little bit DRY and automatic. Something that would be included in all service calls.
Is IDispatchMessageInspector the right thing for me here? What kind of info could that include and can I access that info inside the methods?
Should I create some sort of attribute perhaps for the calls?
If anyone could point me towards a solution for this it would be great.
Edit
Another solution I'm thinking off.
Where the service call to a specific client happens on the consumer side, it will be known at instanceCreation so I could instance the ServiceClient with a known client.
Could I use this solution for the ClientBase<> extender somehow.
Let's say I'm serving Domain1 (let's call the client Domain to not confuse it with a serviceclient/consumer) I create a InformationProvider consumer side that has a ClientBase<IInformationService> field. I ensure that the DomainName (domain1) is set at construction so I could parhaps do the same thing when instancing the ClientBase<IInformationService> so It somehow let's the service know what domain I'm calling for.
I'm just still learning about WCF so I'm not sure how one would do this.
I can understand that you want to keep you solution simple and tidy, but ultimately - as you say yourself -
... I would need some parameter to say from which client...
The obvious and simplest solution is to include a client parameter on all your service calls where it is required. Surely there'll be service calls that don't require the client parameter, and in those cases you don't need to include the parameter.
You may be able to do something clever where a client identifier is passed discreetly under the covers, but beware of doing unnecessarily clever things. I would pass the client as a simple parameter because it is being used as a parameter. Two reasons come to mind:
if someone maintains your code they quickly understand what's going on.
if someone needs to use the service it is obvious how to use it.
A possible pattern:
Make sure you service instantiates per session. This means you'll have to use wsHttpBinding, netTcpBinding, or a custom binding as http does not support sessions.
Always call an initialization operation when each session is instantiated that sets the client id for that service.
Put this initialization operation inside a constructor for a proxy.
The steps involved would be something like this:
[ServiceBehavior(InstanceContextMode=InstanceContextMode.PerSession)]
public class MyService : IMyService
{
private int clientId;
public void StartUp(int clientId)
{
this.clientId = clientId;
and then client side, assuming you use the generated proxy, wrap the client inside another proxy.
public class ExtendedClient : MyServiceClient
{
public ExtendedClient(int clientid) : base()
{
this.StartUp(clientid);
}
Now you should instantiate the ExtendedClient, it will create the channel and prime the service by delivering the client id.
I would personally prefer to simply send the client id for each service call, but if you are able to use a session-able binding then this should work.
Just some information on WCF for you. If you have a stateless service, then you'll need to include the client as a parameter in every service call. This does not mean you need to include the client everywhere throughout your code - you could, for example, retrieve it inside the ClientBase constructor. But you will need to add it to every OperationContract and all the service implementations.
The alternative is to have a stateful service - the instance that you first use will remain for you to reuse (except for timeouts / exceptions). In this case you can potentially send the client just once, and then the service will know about the client for subsequent calls. This is the pattern described above. It means that you cannot use http binding. I believe that by doing this you're only increasing the potential for problems in your application (stateful services, having to ensure the initialization operation completes, more service calls being made).
Using visual studio 2010 RC/.Net 4.0
I have a wcf workflow service with three receive activities defined, basically StartProcessing, StopProcessing, and GetProcessingStatus. This is a long running service that continues to poll an external service for data once StartProcessing is called, until StopProcessing is called.
My problem is with figuring out how to use correlation to ensure that all calls into the service call the same instance of the workflow. I am trying to avoid requiring any sort of instance id be required to be passed back in to subsequent calls to the service. In a nutshell, I would like the workflow being executed to be a singleton, and ensure that all receive activities operate on the same instance. How do I go about doing this?
You can correlate on a constant for example. Edit the XPath in query correlation to return the number 1 for example.
I think that what you want is impossible, you need to correlate, WWF does not know how to execute it. If two parallel calls are received they will use the same object with unexpected results.
In wcf it could be possible, you can set a session in the client or you could manage wcf object creation, but in WWF I think you even don't have that options.