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.
Related
TL;DR:
What is a good and testable way to implement the dependency between the ViewModels and the WCF services in a MVVM client?
Please read the rest of the question for more details about the problems I encountered while trying to do this:
I am working on a silverlight client that connects to a wcf service, and I want to write unit tests for the client.
So I'm looking for a good solution for using the wcf clients in my ViewModels and testing that interaction. I have found two solutions until now:
Solution 1: This is actually how I have implemented it until now:
public class ViewModelExample
{
public ViewModelExample(IServiceClient client)
{
client.DoWorkCompleted += ..
client.DoWorkAsync();
}
}
//This is how the interface looks like
public interface IServiceClient
{
event EventHandler<AsyncCompletedEventArgs> DoWorkCompleted;
void DoWorkAsync();
}
//I was able to put the interface on the generated clients because they are partial classes, like this:
public partial class GeneratedServiceClient : IServiceClient
{
}
The good part: it's relatively easy to mock
The bad part: my service client lives as long as my ViewModel, and when I have concurrent requests I don't know which answer belongs to which request.
Solution 2: Inspired by this answer
WCF Service Client Lifetime.
public class ViewModelExample
{
public ViewModelExample(IServiceFactory factory)
{
var client = factory.CreateClient();
client.DoWorkCompleted += ...
client.DoWorkAsync();
}
}
The good part: each request is on a different client, so no more problems with matching requests with answers.
The bad part: it's more difficult to test. I would have to write mocks for both the factory and the wcf client every time. This is not something I would like to do, since I alreay have 200 tests... :(
So my question is, how do you guys do it? How do your ViewModels talk to the wcf services, where do you inject the dependency, and how do you test that interaction?
I feel that I'm missing something..
Try having a Func<IServiceClient> injected into your VM instead of the a client instance; you'll have a 'language-level factory' injected instead of building a class for this. In the factory method you can instantiate your client however you want (each access could create a new instance for that for example).
The downside is that you'll still have to touch your tests for the most part, but I assume it will be less work:
public ViewModelExample(Func<IServiceClient> factoryMethod)
{
var client = factoryMethod();
client.DoWorkCompleted += ...
client.DoWorkAsync();
}
The WCF service should have it's own tests that confirm the functionality of itself.
You should then be mocking this WCF service and writing unit tests within your consumers.
Unfortunately, it's a pain and something we all have to do. Be pragmatic and get it done, it will save you getting bitten in the future.
Are you using IoC container by a chance? If you had, this problem would be totally mitigated by container (you'll simply register IService dependency to be created as brand new upon each request).
If that's not the case, then
I would have to write mocks for both the factory and the wcf client every time
is how you deal with this kind of "problems". The cost is relatively small, probably 2-3 extra lines of code per test (all you have to do is setup factory mock to return service mock, which you do need either way).
So far I found that MEF is going well with presentation layer with following benefits.
a. DI (Dependency Injection)
b. Third party extensibility (Note that all parties involved should use MEF or need wrappers)
c. Auto discovery of Parts (Extensions)
d. MEF allows tagging extensions with additional metadata which facilitates rich querying and filtering
e. Can be used to resolve Versioning issues together with “DLR and c# dynamic references” or “type embedding”
Pls correct me if I’m wrong.
I'm doing the research on whether to use MEF in Service layer with WCF. Pls share your experience using these two together and how MEF is helping you?
Thanks,
Nils
Update
Here is what my result of research so far. Thanks to Matthew for helping in it.
MEF for the Core Services - cost of changes are not justifying the benefits. Also this is big decision and may affect the service layer in good or bad way so needs lot of study. MEF V2 (Waiting for stable version) might be better in this case but little worried about using MEF V1 here.
MEF for the Function service performs - MEF might add the value but it’s very specific to the service function. We need to go deep into requirement of service to take that decision.
Study is ongoing process, so everyone please share your thoughts and experience.
I think any situation that would benefit from separation-of-concerns, would benefit from IoC. The problem you face here is how you require MEF to be used within your service. Would it be for the core service itself, or some function the service performs.
As an example, if you want to inject services into your WCF services, you could use something similar to the MEF for WCF example on CodePlex. I haven't looked too much into it, but essentially it wraps the service location via an IInstanceProvider, allowing you to customise how your service type is created. Not sure if it supports constructor injection (which would be my preference) though...?
If the WCF service component isn't where you want to use MEF, you can still take advantage of MEF for creating subsets of components used by the service. Recently for the company I work for, we've been rebuilding our Quotation process, and I've built a flexible workflow calculation model, whereby the workflow units are MEF composed parts which can be plugged in where needed. The important part here would be managing how your CompositionContainer is used in relation to the lifetime of your WCF service (e.g. Singleton behaviour, etc.). This is quite important if you decide to create a new container each time (container creation is quite cheap, whereas catalog creation can be expensive).
Hope that helps.
I'm working on a solution where the MEF parts that I want to use across WCF calls are stored in a singleton at the application level. This is all hosted in IIS. The services are decorated to be compatible with asp.net.
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
In Global.asax, I import the parts.
[ImportMany(typeof(IOption))]
public IEnumerable<IOption> AvailableOptions{ get; set; }
After initializing the catalog and container, I copy the imported objects to my singleton class.
container.ComposeParts(this);
foreach (var option in AvailableOptions)
OptionRegistry.AddOption(option);
EDIT:
My registry class:
public static class OptionRegistry
{
private static List<IOption> _availableOptions= new List<IOption>();
public static void AddOption(IOption option)
{
if(!_availableOptions.Contains(option))
_availableOptions.Add(option);
}
public static List<IOption> GetOptions()
{
return _availableOptions;
}
}
This works but I want to make it thread safe so I'll post that version once it's done.
Thread-safe Registry:
public sealed class OptionRegistry
{
private List<IOptionDescription> _availableOptions;
static readonly OptionRegistry _instance = new OptionRegistry();
public static OptionRegistry Instance
{
get { return _instance; }
}
private OptionRegistry()
{
_availableOptions = new List<IOptionDescription>();
}
public void AddOption(IOptionDescription option)
{
lock(_availableOptions)
{
if(!_availableOptions.Contains(option))
_availableOptions.Add(option);
}
}
public List<IOptionDescription> GetOptions()
{
return _availableOptions;
}
}
A little while ago i was wondering how I could create a WCF web service that will get all of its dependencies wired by MEF but that i wouldnt need to write a single line of that wire up code inside my service class.
I also wanted it to be completely configuration based so i could just take my generic solution to the next project without having to make code changes.
Another requirement i had was that i should be able to unit-test the service and mock out its different dependencies in an easy way.
I came up with a solution that ive blogged about here: Unit Testing, WCF and MEF
Hopefully will help people trying to do the same thing.
I'm creating a service reference to a web service written in Java. The generated classes now follow the Java casing convention used in the web service, for example class names are camelCase rather than PascalCase.
Is there a way to get the desired casing from the service reference?
CLARIFICATION:
With WSE based services, one could modify the generated Reference.cs to provide .NET standard casing and use XmlElementAttribute to map to the Java naming presented by the external web service, like this:
[System.Xml.Serialization.XmlElementAttribute("resultType", Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
[System.Runtime.Serialization.DataMember]
public virtual MyResultType ResultType
{ ... }
Not terribly maintenance-friendly without writing custom code to either generate the proxy code or modify it after it's been generated.
What I'm after is one or more options to present a WCF generated client proxy to calling applications using the .NET casing conventions, achieving the same as I did previously with WSE. Hopefully with less manual effort.
Well, since your WCF client proxies are partial classes, you could always add a second file for the same class, which implements the PascalCasedMethodName for each javaCasedMethodName and then just call the Java method from your new method.
public partial class MyClientProxy
{
......
public MyResultType GetResultType(string inputParam)
{
return this.getResultType(inputParam);
}
......
}
Seems a bit redundant - but that should really work, I think. Since your code is stored in a separate file, it won't be overwritten if you re-create the client proxy - and since it's the second part of a partial class, it will be "merged into" the class definition for your client code to call.
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.
Adding a service reference to a web service (this is all WCF) in Visual Studio produces some generated code including a client-side restatement of the interface being exposed.
I understand why this interface is generated: you might be consuming a 3rd party service and not have access to the actual interface.
But I do, and the two are not assignment compatible even though the transparent proxy does indeed exactly implement the interface to which I want to cast.
I can use reflection, but that's ugly. Is there some way to defeat this faux type safety and inject metadata to so I can use an interface with a class?
My specific problem departs from the norm in complicated ways that have to do with a single client that uses some derivatives of a base class directly and uses others remotely via service references. The base class for each server needs to keep references to subscribing clients in a collection for enumeration to notify events, and the problem was type varied due to the use of proxies.
None of these answers solves my specific problem, yet every single answer was instructive and helpful. I found my own solution (use a dual binding) but I would never have figured it out if you hadn't radically improved my understanding of the whole business.
Three excellent answers. How to choose just one? I choose the first, because it directly solves the problem I first thought I had.
If you already have the contract dll at the client, you don't even need a service reference (unless you are using it to write the setup code for you) - you can simply subclass ClientBase and expose the Channel, and use that directly - something like (no IDE handy...):
public class WcfClient<T> : ClientBase<T> where T : class
{
public new T Channel {get {return base.Channel;}}
}
Then you can just do things like:
using(var client = new WcfClient<IFoo>())
{
client.Channel.Bar(); // defined by IFoo
}
You still need the configuration settings in the config to determine the address, binding, etc - but less messy than proxy generation. Also, you might choose to re-implement IDipsoable to deal with the fact that WCF proxies can throw in Dispose() (which is bad):
public class WcfClient<T> : ClientBase<T>, IDisposable where T : class
{
public new T Channel {get {return base.Channel;}}
void IDisposable.Dispose() {
try {
switch(State) {
case CommunicationState.Open: Close(); break;
// etc
}
} catch {} // swallow it down (perhaps log it first)
}
}
When you add the service reference, go to "Advanced" and make sure "Reuse types in referenced assemblies" is selected and that the assembly containing your interface definition is selected. You can also do this with an existing service reference by right clicking on it and going to "Configure".
In order to return an interface from a service you need to use the KnownType attribute:
http://weblogs.asp.net/avnerk/archive/2006/07/31/WCF-Serialization-part-1_3A00_-Interfaces_2C00_-Base-classes-and-the-NetDataContractFormatSerializer.aspx
If you want to return a custom type from the service:
http://msdn.microsoft.com/en-us/library/bb628653.aspx
Does any of that help?