I want to make my first WCF service but I am unsure of how to structure it.
the serivce will take requests to retrieve different types of items from my database:
List<Product> getProducts()
List<Module> getModules(Product)
List<Releases> getReleases(Product)
List<Feature> getFeatures(Product,Module)
//many more types of items to get etc...
//and then the equivalent functions to update those item types back in the database...
So should I implement all of this as a single service contract?
[ServiceContract]
public interface IMyService{}
public class MyService : IMyService{}
I understand this way I would only have to host one service but could this become bogged down with heavy traffic trying to serve lots of people all the possible requests they could make?
or should I have a different service contract for each type of item and have each one implemented separately so I could host each of them on separate machines to reduce poor performance from possible times of heavy traffic?
[ServiceContract]
public interface IMyProductService{}
public class MyProductService : IMyProductService{}
[ServiceContract]
public interface IMyModuleService{}
public class MyModuleService : IMyModuleService{}
[ServiceContract]
public interface IMyUserService{}
public class MyUserService : IMyUserService{}
... etc etc ...
I would have the single implementation of all the contracts. Something like:
public interface IUserService{}
public interface IYourModuleService{}
public interface IYourProductService{}
public class YourService : IUserService, IYourModuleService, IYourProductService{}
That way you can also control your clients only use the contracts they need, but also (unless youre expecting massive volume)your implementation design should be the first port of call for any bottle necks, rather than contract design.
Also you can use all of the WCF Tools 'out of the box' to control volume and instances and so on - to streamline your processes.
So in short - single implementation, multiple service contracts.
Related
One guy explained this way but not very clear to how to implement it.
From experience:
Using different binding, for example one BasicHttpBinding for Java clients while using WsHttpBinding for .NET clients. Also HTTPS for some and HTTP for others...
Dividing and exposing different contracts/interfaces. For example you have one interface that exposes many operations and you have a cut down interface which does basic things and you publish the second to outside so internal clients use the endpoint for extended interface but external clients use the other one.
For example
interface IFoo
{
void DoBasic();
}
interface IFooInternal : IFoo
{
void DoMore();
}
Now you have One class implementing both:
public class Foo : IFooInternal
{
....
}
And now you expose only one to outside while implementation is in the same class.
the things which i do not understand how to design my service contract in such a way that few operation i will expose to other client and extended feature i will expose to internal client. so if possible just make me understand giving me a small program & code that how it can be possible through multiple endpoints in WCF service. thanks
I'm in the process of writing a duplex WCF service using NetTcpBinding, and I've run into an architecture question that I think I know the answer to, but hope that I'm wrong.
Our service is stateful, and we've selected NetTcpBinding with PerSession InstanceContextMode. For various reasons, this is something that we require. I'm trying to break up our larger interface (where large blocks of the operations would not apply to many clients) into multiple smaller interfaces with the operations logically grouped. While it's simple enough to have a single service implementation implement all of the contracts, I'm not sure if it's possible to have multiple service contracts share a single channel (or, more to my requirement, a single session), and I'd definitely need to be able to do that in order to make this work.
I could, of course, include everything on one contract and throw FaultExceptions when an invalid operation is performed, but I'd really like to be able to break these up and not even add an endpoint for inapplicable contracts. Is what I'm looking for possible?
TL;DR Version:
I need to be able to do this:
[ServiceContract]
public interface IServiceA
{
[OperationContract]
void Foo();
}
[ServiceContract]
public interface IServiceB
{
[OperationContract]
void Bar();
}
[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerSession)]
public class Service : IServiceA, IServiceB
{
...
}
And be able to establish one session from the client to the service but use both IServiceA and IServiceB.
The default instance provider over a sessionful channel will give you an instance per connection in your case. You can however extend the instance provider to pick up an existing object from your own cache and return the same object.
How you correlate instances will be upto you using some special message header etc. The underlying channel/Connection will be different for each proxy and also use differnt buffers / concurrency models but you can allow service model to use the same instance.
http://msdn.microsoft.com/en-us/magazine/cc163590.aspx
I am designing a web service which will call different external web services according to the properties of a given object (a "request", for instance). A reference to these web services is added through the "Add Web Reference" menu in Visual Studio 2008, which, as you know, creates a proxy class for each endpoint which inherits from System.ServiceModel.ChannelBase<ISomeInterface> (where ISomeInterface is the endpoint defined by the specific service's WSDL).
The question is that I would like to encapsulate all those proxies in a single ServiceManager (for instance) static class containing, for example, an internal list of all the proxies, so that, on the one hand, all calls to a given service may go through ServiceManager instead of being scattered around the main application, and, on the other hand, new services which may be added latter can be made known to ServiceManager by a simple addition of a reference to the new proxy class.
I thought about desinging ServiceManager like
public static class ServiceManager
{
#region Properties
public static Dictionary<string, TProxy> ServiceList { get; private set; }
#endregion
}
but I don't know what I should replace TProxy by so that all of the different proxies can be called by using ServiceManager.ServiceList["ServiceName"]. Can anyone please help me out with this?
Since each service implements a different interface, it would have to be object... Unless you can create a common base interface, make the proxies inherit from that interface, and then create a List<MyBaseInterface>.
Why can't you just have one property on your class per proxy? At least then you could access the proxies in a strongly-typed way.
Do not reuse proxies. Re-instantiate them. Magic strings to differentiate between proxies are equally bad.
You are better off using static factories that return your service proxies than you are keeping only one instance of them.
Something like this:
public static class ServiceFactory
{
public static Proxy CreateProxy();
public static Proxy2 CreateProxy2();
// etc.
}
I've got a WCF service with lots of method and DataContracts. It is usually consumed by large application "A". I want to create a tiny application "B" which will use the very same server but only a few methods from the service. I want to reduce the size of the XAP, and since the client is using a fraction of all methods exposed by the service, I'd like to have a smaller service reference file than the one automatically created by Visual Studio. I can remove methods which are not used manually but then I cannot really use update service command.
Any solutions?
Many thanks,
Karol
OK, so you have a complete IGreatService interface with lots of methods, which are implemented on a MyGreatService class.
How about this: you create a new, second interface IMyServiceB which has only those few methods you want to expose to the second group of users. You make it so your service implements both IGreatService and IMyServiceB (that's absolutely possible, no problem):
public class MyGreatService : IGreatService, IMyServiceB
{
..
}
Service B basically then just calls those few methods in the service implementation that you want to expose - let's say, you have MethodA on IGreatService that you want to expose on IMyServiceB as well (as MethodB) - implement it like that:
public class MyGreatService : IGreatService, IMyServiceB
{
....
// as defined on IGreatService
public void MethodA (....)
{
}
....
public void MethodB (.....) // as defined on IMyServiceB
{
MethodA();
}
}
That way, you get two separate interfaces (= services), but basically you write your code only once.
You can then expose IMyServiceB on a distinct and separate endpoint, so that users who are supposed to only see IMyServiceB can just connect to that separate endpoint, and they'll only get whatever they need to use your service-B operations.
Could that work?
Marc
We are developing a WCF based system. In the process we are trying to lock some data from being modified by more than one users. So we decided to have a data structure that will contain the necessary information for the locking logic to execute (by for example storing the ID of the locked objects)
The problem we are having is persisting that data between sessions. Is there anyway we can avoid executing expensive database calls?
I am not sure how can we do that in WCF since it can only persist data (in memory) during an open session.
Static members of the service implementing class are shared between sessions & calls.
One option would be to use static members as Jimmy McNulty said. I have a WCF service that opens network connections based on a user-specified IP address. My service is configured for PerCall service instance mode. In each session, I check a static data structure to see if a network connection is already opened for the specified IP address. Here's an example.
[ServiceContract]
public interface IMyService
{
[OperationContract]
void Start(IPAddress address);
}
[ServiceBehavior(InstanceContextMode=InstanceContextMode.PerCall)]
public class MyService : IMyService
{
private static readonly List<IPAddress> _addresses = new List<IPAddress>();
public void Start(IPAddress address)
{
lock(((ICollection)_addresses).SyncRoot)
{
if (!_addresses.Contains(address)
{
// Open the connection here and then store the address.
_addresses.Add(address);
}
}
}
}
As configured, each call to Start() happens within its own service instance, and each instance has access to the static collection. Since each service instance operates within a separate thread, access to the collection must be synchonized.
As with all synchronization done in multithreaded programming, be sure to minimize the amount of time spent in the lock. In the example shown, once the first caller grabs the lock, all other callers must wait until the lock is released. This works in my situation, but may not work in yours.
Another option would be to use the Single service instance mode as opposed to the PerCall service instance mode.
[ServiceBehavior(InstanceContextMode=InstanceContextMode.Single)]
public class MyService : IMyService
{ ... }
From everything I've read, though, the PerCall seems more flexible.
You can follow this link for differences between the two.
And don't forget that the class that implements your service is just that - a class. It works like all C# classes do. You can add a static constructor, properties, event handlers, implement additional interfaces, etc.
Perhaps a caching framework like velocity help you out.
Create a second class and set its InstanceContextMode to single and move all the expensive methods there, then in your original class use that methods.