Our applications use a lot of shared components. Some of them have no need for caching, for example, Windows Services which process unmailed emails. You'd never cache that result set...
Problem is, since our shared data layer has been modified to use SqlCacheDependency, our services which don't start SqlDependency fail on database calls where the data layer requests a SqlCacheDependency object.
Which leads to the question - is there a way for our data classes to test to see if the broker service is listening (ie: has SqlDependency.Start(connectionString) been called)?
The SqlDependency object itself has no Enabled or similar property. Is there any way short of forcing the calling app to tell the data layer that SqlCaching is in use for the data layer to determine the state?
Pretty much the answer is no. We ended up adding a config variable that if false or not present, causes the request to use SqlCacheDependency to be skipped.
SELECT * FROM sys.service_queues WHERE name LIKE 'SqlQueryNotificationService-%'
returns a 'SqlQueryNotificationService-[some guid]'
And if you look deep in the Non-public members of the SqlDependency _serverUserHash while debugging in the IDE, you'll find a collection that contains that same entry. If Microsoft would be so kind as to expose that, then yes.
In my case I have a class library which is used by some web applications. So I have no App.config. I also use the SqlCacheDependency in a static event. So I'm using a static boolean like:
if (!isCachingEnabled)
isCachingEnabled = SqlDependency.Start(builder.ProviderConnectionString);
So far is working but I'm open to suggestions when using Class Libraries.
Related
I am creating a WFC Restful service and there is a need to persist a variable that will be persist per user, is there a way I can achieve this without having to pass the variable to all my calls?
I am using trying to log the process of the user throughout the process, weather their request has failed or succeed, IP address, when they requested the action, failure time, etc.
Please note I am new to WCF, thanks in advance.
I recently worked on this (except it wasn't RESTFUL). You could transmit information through HTTP headers and extract that information on the service-side. See http://trycatch.me/adding-custom-message-headers-to-a-wcf-service-using-inspectors-behaviors/
For the client ID itself I can suggest two places to put it. One is OperationContext.Current.IncomingMessageProperties. Another is CorrelationManager.StartLogicalOperation which allows you to define a logical operation - that could be the service request, beginning to end - or multiple operations - and retrieve a unique ID for each operation.
I would lean toward the latter because it's part of System.Diagnostics and can prevent dependencies on System.ServiceModel. (The name CorrelationManager even describes what you're trying to do.)
In either case I would look at interception. That's the ideal way to read the value (wherever you store it) without having to pollute the individual methods with knowledge of logging and client IDs. (I saw from your message that you're trying to avoid that direct dependency on client IDs.)
Here's some documentation on adding Windsor to your WCF service. (At some point I'll add some end-to-end documentation on my blog.) Then, when you're using Windsor to instantiate your services, you can also use it to instantiate the dependencies and put interceptors around them that will perform your logging before or after those dependencies do their work. Within those interceptors you can access or modify that stack of logical operations.
I'm not doing Windsor justice by throwing out a few links. I'd like to flesh it out with some blog posts. But I recommend looking into it. It's beneficial for lots of reasons - interception just one. It helps with the way we compose services and dependencies.
Update - I added a blog post - how to add Windsor to a WCF service in five minutes.
I have a wcf web service which i want to share information between calls (diferent clients calls) .
for example sharing a dictionary between client calls. the dictionary can be change through calls (add/remove item etc) but i cant efford it to be deleted or to be renew for each call (it should be like a static database) .
is there any way to implement this issue?
allready tried a few suggestions but nothing realy seems to work.
You basically need a singleton defined outside of your service class - you would need to handle the very likely possibility that multiple calls will be accessing / modifying the info at the same time so will need to lock the data maybe with a ReaderWriteLock or ReaderWriterLockSlim.
A nicer way of doing it, assuming you are using .net 4.0, would be to use MemoryCache, which contains built-in thread safety. If you are pre .net 4.0, there is a cache object in the System.Web namespace link - it was a bit of a pain having to add reference to system.web if you wanted to use it when writing windows apps so the MemoryCache implementation in .net 4.0 was a welcome addition.
Ok so I have built my WCF service and its functioning great! However, I am starting to implement it into our pre-existing piece of software now and I am instantly running into the question, do I only use the proxy generated code and get rid of the dll that I used initially? Or do I keep both, and make distinctions between the two very obvious?
What I mean by keeping distinctions is, having a ServerUser and a LocalUser property that represent the same user object. However, my LocalUser property would be filled via the dll that the app initally ran with, if the application service is unavailable.
My main reasoning for this thought pattern is that if I remove my dll, I have a single point of failure. If for some reason my ServiceHost is just not up and running, but the DB server is, I would want my users to still be able to do their job. The features that the new WCF implementation utilize are not dependant for employees to do their job. It is more of a convenience in what the WCF service provides. Also, building in this kind of logic to the Service would allow service modifications more readily available in a non IIS hosted environment.
Also, is there a way to build in logic on the service so that when I pull down the proxy code for the client that it just knows to access the DB manually if the ServiceHost is unavailable? If this was a possibility, I think about 90% of all my problems would disappear.
Thank you in advance!
From what you describe it sounds like keeping your existing DLL, i.e. direct access to the DB, would best suit your needs. Having a WCF service adds nothing if, when it fails, you'll just use the DLL anyway.
Ideally you would go with the WCF service completly and offer some kind of redundency to deal with any potenial service issues. Plus, using a service will mean you won't have to deal with any DLL upgrades/deployments.
But, from your question, it sounds like there would be some real issues to deal with should the service not be available, so just do with the DLL.
EDIT: Just read the last part of your question and I don't think that is possible. The proxy code for accessing services is generated when you add the reference to your project. The kind of "dynamic" information you're after would actually require a service.
EDIT: As a follow up to my comment below you could test this by creating a DLL and class, lets call it Class1. Then create a WCF service with a method that will return Class1. Create a client application and add a reference to the service. If you look at the proxy-generated code you should see (hopefully...I'm thinking of this as I type :)) that the method returns Class1, but when you compile it won't be able to find Class1. This is because Class1 does not have the DataContractAttribute which would auto-generate Class1 on the client. So, you have to distribute the shared DLL to the client. Now when the method returns and WCF tries to re-create Class1 it will use the local version in the shared DLL. Your other DLL, which will already be on the client, would use the same shared DLL.
First off, I wish context based storage was consistent across the framework!
With that said, I'm looking for an elegant solution to make these properties safe across ASP.NET, WCF and any other multithreaded .NET code. The properties are located in some low-level tracing helpers (these are exposed via methods if you're wondering why they're internal).
I'd rather not have a dependency on unneeded assemblies (like System.Web, etc). I don't want to require anyone using this code to configure anything. I just want it to work ;) That may be too tall of an order though...
Anyone have any tricks up their sleeves? (I've seen Spring's implementation)
internal static string CurrentInstance
{
get
{
return CallContext.LogicalGetData(currentInstanceSlotName) as string;
}
set
{
CallContext.LogicalSetData(currentInstanceSlotName, value);
}
}
internal static Stack<ActivityState> AmbientActivityId
{
get
{
Stack<ActivityState> stack = CallContext.LogicalGetData(ambientActivityStateSlotName) as Stack<ActivityState>;
if (stack == null)
{
stack = new Stack<ActivityState>();
CallContext.LogicalSetData(ambientActivityStateSlotName, stack);
}
return stack;
}
}
Update
By safe I do not mean synchronized. Background on the issue here
Here is a link to (at least part of) NHibernate's "context" implementation:
https://nhibernate.svn.sourceforge.net/svnroot/nhibernate/trunk/nhibernate/src/NHibernate/Context/
It is not clear to me exactly where or how this comes into play in the context of NHibernate. That is, if I wanted to store some values in "the context" would I get "the context" from NHibernate and add my values? I don't use NHibernate, so I don't really know.
I suppose that you could look and determine for yourself if this kind of implementation would be useful to you. Apparently the idea would be to inject the desired implementation, depending on the type of application (ASP.NET, WCF, etc). That probably implies some configuration (maybe minimal if one were to use MEF to load "the" ICurrentSessionContext interface).
At any rate, I found this idea interesting when I found it some time ago while searching for information on CallContext.SetData/GetData/LogicalSetData/LogicalGetData, Thread.SetData/GetData, [ThreadStatic], etc.
Also, based on your use of CallContext.LogicalSetData rather than CallContext.SetData, I assume that you want to take advantage of the fact that information associated with the logical thread will be propagated to child threads as opposed to just wanting a "thread safe" place to store info. So, if you were to set (pr Push) the AmbientActivity in your app's startup and then not push any more activities, any subsequent threads would also be part of that same activity since data stored via LogicalSetData is inherited by child threads.
If you have learned anything in the meantime since you first asked this question I would be very interested in hearing about it. Even if you haven't, I would be interested in learning about what you are doing with the context.
At the moment, I am working on maintaining some context information for logging/tracing (similar to Trace.CorrelationManager.ActivityId and Trace.CorrelationManager.LogicalOpertionStack and log4net/NLog context support). I would like to save some context (current app, current app instance, current activity (maybe nested)) for use in an app or WCF service AND I want to propagate it "automatically" across WCF service boundaries. This is to allow logging statements logged in a central repository to be correlated by client/activity/etc. We would be able to query and correlate for all logging statements by a specific instance of a specific application. The logging statements could have been generated on the client or in one or more WCF services.
The WCF propagation of ActivityId is not necessarily sufficient for us because we want to propagate (or we think we do) more than just the ActivityId. Also, we want to propagate this information from Silverlight clients to WCF services and Trace.CorrelationManager is not available in Silverlight (at least not in 4.0, maybe something like it will be available in the future).
Currently I am prototyping the propagation of our "context" information using IClientMessageInspector and IDispatchMessageInspector. It looks like it will probably work ok for us.
Regarding a dependency on System.Web, the NHibernate implementation does have a "ReflectiveHttpContext" that uses reflection to access the HttpContext so there would not be a project dependency on System.Web. Obviously, System.Web would have to be available where the app is deployed if HttpContext is configured to be used.
I don't know that using CallContext is the right move here if the desire is simply to provide thread-safe access to your properties. If that is the case, the lock statement is all you need.
However, you have to make sure you are applying it correctly.
With CallContext, you are going to get thread-safe access because you are going to have separate instances of CallContext when calls come in on different threads (or different stores, rather). However, that's very different from making access to a resource thread-safe.
If you want to share the same value across multiple threads, then the lock statement is the way to go. Otherwise, if you want specific values on a per-thread/call basis, use the CallContext, or use the static GetData/SetData methods on the Thread class, or the ThreadStatic attribute (or any number of thread-based storage mechanisms).
Should I bind directly to objects returned from a webservice or should I have client-side objects that I bind to my gridcontrols? For instance if I have a service that returns object Car should I have a client side Car object that I populate with values from the webservice Car object?
What is considered best-practice?
In C# do I need to mark my classes as serializable or do something special to them?
This is a good question, which follows the sames lines as two questions I have asked myself:
Large, Complex Objects as a Web Service Result.
ASP.NET Web Service Results, Proxy Classes and Type Conversion.
Both of these may be a worthwhile read for you.
Heres my two bits:
Try to keep the return types of your Web Services to primitives where possible. This not only helps reduce the size of the messages, but also reduces complexity at the receiving end.
If you do need to return complex objects, return them as a raw xml string (I'll explain below).
What I then do is create a seperate class which represents the object and handles it's xml. I ensure the class can be instantiated from and serialized to xml easily. Then both projects (the web service and the client) can reference the DLL with the concrete object in, but there is none of the annoying coupling with the proxy class. This coupling causes issues if you have shared code.
For example (using your Car class):
Web Service (CarFactory) method BuyCar(string make, string model) is a factory method that returns a car.
You also write a Mechanic class that works on Car objects to repair them, this is developed without knowledge of the Web Service.
You then right a Garage class for your application. You add a web reference to the CarFactory service to get your cars, and then add some Mechanic's to your garage and then crack your knuckles and get ready to get some cars from the factory to get them working on.
Then it all falls over, when you get the result of CarFactory.BuyCar("Audi", "R8") and then tell your Mechanic.Inspect(myAudi) the compiler moans, because the Car is actually of type CarFactory.Car not the original Car type, yes?
So, using the method I suggested:
Create your Car class in its own DLL. Add methods to instantiate it and serialize it from/to XML respectively.
Create your CarFactory web service, add a reference to the DLL, build your cars as before, but instead of returning the object, return the XML.
Create your Garage adding a reference to the Mechanic, Car DLL and the CarFactory web service. Call your BuyCar method and now it returns a string, you then pass this string to the Car class, which re-builds its object model. The Mechanic's can happily work on these Car's too because everything is singing from the same hymn sheet (or DLL?) :)
One major benefit is that if the object changes in its design, all you need to do is update the DLL and the web service and client apps are completely decoupled from the process.
Note: Often it can be useful to then create a Facade layer two work with the web services and auto-generate objects from the XML results.
I hope that makes sense, if not, then please shout and I will clarify .
This really depends on what you are getting from the web service. If they are simple data transfer objects and you are only displaying data, then yes, you can bind. If you plan to edit the objects, it may not be usefull as you will need to track changes.
Do your objects and/or collections on the client track changes? If so you can use them.
If you have no change tracking, then you will need to track changes yourself, so you may need to translate the objects or wrap them in something to track changes.
Again, it really depends on what you are getting, what they support, what you are doing with them, as well as what response the server wants back for changes.
One thing you can do is to create client classes corresponding to the web service data contracts with any additional functionality that you want and set the web service reference to reuse existing types. Then there is no reason to create an additional wrapper class to bind to.
If you bind directly to the Web service types, you're introducing a coupling. Should the Web service change in future, this may have undesired side-effects that mean lots of code changes.
For example, what if you're using .asmx Web services today, then shift to WCF tomorrow? That might mean quite a few changes through your code if you've used types that WCF won't serialize.
It's often better in the long run to create specific client-side objects and then translate to and from Web service data contract types. It may seem a lot of work, but this is often repaid greatly when it's time to refactor, as your changes are localised in one place.
If you are the owner of both the web service and the client.
And you need the parameters of the web service calls to be complex classes which contain not only data but also behavior (actual coded logic) then you are in a bit of a pickle when developing these web services using web service frame works.
As suggested in the answer by Rob Cooper you can use pure xml as web service parameters and xml serialization, but there is a cleaner solution.
If you are using Visual Studio 2005 (probably applies the same for 2008), You can customize the way VS creates you proxy as described in this article:
Customizing generated Web Service proxies in Visual Studio 2005
This way you can tell VS to use your own classes instead of generating a proxy class.
Well when I think of it, it's pretty much same solution as proposed by Rob Cooper, with the little twist, that you wont be writing a Facade layer your self but will be using VS itself as this layer.