How do I pass a service to another plugin? - wcf

I have a plugin that I will instantiate at runtime and I want to pass it a WCF service from the application host. The application host is responsible for creating the connection to the service. The reason for this is that a single service can be used by multiple plugins, but the plugins should only know about its interface since there may be several implementation of IMyPluginServices. For instance, the Run method of the plugin instance would be:
public void Run(IMyPluginServices services)
{
services.DoSomething();
}
The problem I am running into is that I don't know how to create a service of type IMyPluginServices and pass it to the Run function. The service reference generated by VS 2010 doesn't seem to create an object of type IMyPluginServices that I can pass to it. Any help would be greatly appreciated. Thanks.

When you add a service reference in VS 2010 for a service it generates an interface named IMyService which contains methods for each OperationContract in your service. It also generates a concrete class named MyServiceClient, which can be constructed and then used to invoke your service.
Now, the problem that you're running into, I believe, is that MyServiceClient is a subclass of ClientBase<IMyService>, and does not implement the generated IMyService interface (which is a real pain).
To get around this problem I ended up making a new interface:
public interface IMyServiceClient : IMyService, IDisposable, ICommunicationObject
{
}
(Note: IDisposable and ICommunicationObject are only required if you want your module to be able to detect/react to faulted channels and other such things).
I then extend MyServiceClient with a partial class (in the assembly that contains my WCF Service reference):
public partial class MyServiceClient : IMyServiceClient
{
}
Now in my modules I can accept an IMyServiceClient instead of an IMyService, and still execute all of the methods that I need to. The application in control of the modules can still create instances of MyServiceClient as it always did.
The beauty of this is that your new interface and partial class don't need any actual code - the definitions suffice to get the job done.

Related

WCF: Select between regular and duplex service contract at runtime

I am writing a WCF client/service. The service can perform some long operations so I have added a callback contract IProgressCallback. The system I am developing has to run in all kind of environments so I suspect that I will run into an environment where a callback channel cannot be opened (I might be wrong here).
So to be careful I have defined the operation contract like this.
[ServiceContract()]
interface IContract
{ ... }
[ServiceContract(CallbackContract = typeof(IProgress))]
interface IDuplexContract : IContract
{ ... }
This works great on the server side. I can easily configure the service to use either contract.
The problem however arises on the client side. I have manually defined 2 proxies
public class ContractProxy
: ClientBase<IContract>, IContract
{ ... }
public class DuplexContractProxy
: DuplexClientBase<IDuplexContract>, IDuplexContract
{ ... }
Again both proxies work fine.
Now I have a proxy factory which is responsible for creating the correct proxy. It can easily figure out which proxy to instantiate but my problem arises when I try to return the proxy.
The user needs to get an object back that is at least IContract and ICommunicationObject but I haven't been able to find what to return. I have tried to the following:
IContract CreateProxy(...) // The user lacks access to Open, Abort, Close, etc.
ClientBase<IContract> CreateProxy(...) // DuplexClientBase derives from ClientBase but the generic parameter is different and it isn't covariant so this cannot be done.
// First define a generic interface and then make both proxies implement it.
IProxy<TContract> : TContract, ICommunicationObject // TContract cannot be restricted to an interface so I cannot make IProxy derive from TContract
Currently as a workaround I am simply returning the IContract interface but then everyone using the proxy will have to start by casting it to a ICommunicationObject to open the proxy etc.
Does anyone here have a better way to do this or am I simply being overly worried that duplex communication might not work in some environments?

WCF Calling C# Methods

I used to code only in databases enviroments. Recent changes in the corp. made me start developing in whole new worlds.
This new project is something like SQL - C# - PHP.
The class I've been working on in VS2008 is almost dnoe. It calls all the SQL SPs I need and the info is there in the DataReaders.
When It came to read that info from PHP so I could populate the website I found out it wasn't that easy. I was recommended into trying several options, the one that suits the best for the project is to create a Web Service and then consume it (please be patient, As I just stated I'm new to most web related programming)
So, I'm trying to WCF/Rest and then consume it from PHP but I haven't got there yet.
I've read and watched several tutorials on WCF and It seems to be smooth, but all I've read is:
. Create Interface with its OperationContracts.
. Create Service with DataMembers etc and define the Methods listed in the Interface.
Ok, but what I'd like to do is not to specify any methods there, since all I want is to call C# method I've already written.
Should I do that in the Service or in the Interface? And first of all, is this the right the way to approach it?
You would want to write service methods that implement an operation contract interface. The service methods can call the C# code that you've already written.
For example, here is a simple service interface:
[ServiceContract]
public interface IYourService
{
[OperationContract]
int GetCountOfTransactions(string filter);
}
And then you would implement this interface in your service class:
public class YourService : IYourService
{
public int GetCountOfTransactions(string filter)
{
// Call your existing code
YourClass yourClass = new YourClass();
return yourClass.GetCountOfTransactions(filter);
}
}
There are plenty of examples out there for setting this up as a REST service, but I think you're on the right track.
The trickiest part is usually setting up the binding configuration to make sure all of your consuming client applications can connect.
Hopefully this helps.

Encapsulating WCF Proxies in Static Classes

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.
}

Dependency Injection with WCF proxy

I have a service (Service1) that uses another serice (Service2). I am using Dependency injection for both services and need to inject the proxy for Service2 into Service1.
I am unsure how to deal with the fact that the proxy is not a simple class of type IService2 but a proxy inheriting from ClientBase as well. Obviously my Service1 implementation needs to open the proxy and should also close it after use or abort it if an exception occurs but if I am just injecting an instance of IService2 then I cannot do this (without casting) because the Open, Close and Abort methods are on the base class whilst my operations are on the interface.
When it comes to testing Service1, I would expect to mock just the interface but if the Service1 implementation expect Open, Close and Abort methods, then this is tricky. In the past, I have done something hacky like this but there must be a better way!
var proxyBase = _service2 as ClientBase;
if (proxyBase != null)
{
proxyBase.Open();
}
_service2.DoOperation("blah"); //the actual operation
if (proxyBase != null)
{
proxyBase.Close();
}
// repeat for Abort in exception handler(s).
What are other people doing?
Thanks
The auto generated class that you get for adding a service reference for a WCF service is implemented as a partial class. What I do is create a another partial file for that class and implement an interface that exposed those methods, and then use that interface where you would normally use the ClientBase or WCF interface
public partial class Service2 : IClientService2
{}
If IClientService2 has the Abort and Close methods that match the ClientBase methods it should be all you need.
public interface IClientService2 : IService2 // where IService2 is the WCF service interface
{
void Abort();
void Close();
}
I suggest injecting a factory to construct WCF services rather than injecting the proxy itself since when a fault occurs then the channel is no longer able to be used and you will need to construct a new proxy.
IClientService2 proxy = _service2Factory.Create();
proxy.Open();
proxy.DoOperation("blah"); //the actual operation
proxy.Close();
Your interface is poluted because of the requirements imposed by Wcf. If you were not using wcf you would not have an Open and Close method. In an ideal world the interface should look the same as if the service was in process.
Have you chosen your IoC container yet? If you haven't I would consider looking at Windsor. This will allow you to maintain a clean interface and either inject the service as an in process object or a wcf proxy.
container = new WindsorContainer().AddFacility<WcfFacility>();
container.Register(Component
.For<IClientService2>()
.ActAs(DefaultClientModel)
.On(WcfEndpoint.FromConfiguration("YourServiceNameInConfiguration")))
.LifeStyle.Transient);
The WcfFacility will do all the opening and closing of the channel for you.
I ended up using this approach which uses Castle Dynamic Proxy to intercept calls and handle WCF specifics. It works really well and allows the class where the proxy is injected to treat it like a normal class / interface. This class is then totally unit testable by mocking the service contract interface.

How to create a trimmed service in WCF

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