Using wcf services in S#arp Architecture project - wcf

I have a sharp architecture project and I am making use of ApplicationServices in it as well.
There is requirement to provide a winform client that will use a wcf service. The wcf service will in turn use the ApplicationServices. I have not started working on the winform client yet but I am working on the wcf service.
Following the Northwind sample. I have created a "Wcf Service library" project and a "Wcf Service Application" project in my solution.
I am new to wcf but i know all the basics and have worked with web services alot in the past. I have following questions:-
1) I would like to know why there is a need of two projects, wcf library and wcf application?
2) I have noticed that the ITerritoriesWcfService interface in the Northwind sample inherits ICloseableAndAbortable.
public interface ITerritoriesWcfService : ICloseableAndAbortable
What is the purpose of ICloseableAndAbortable?
3) There is another class TerritoriesWcfServiceClient
public partial class TerritoriesWcfServiceClient : ClientBase<ITerritoriesWcfService>, ITerritoriesWcfService
What is the purpose of this class?
4) In the TerritoriesService.svc file, what is the purpose of Factory="SharpArch.Wcf.NHibernate.ServiceHostFactory, SharpArch.Wcf" ? Usually in a normal wcf service application, I use codebehind attribute, but since the .cs file actually resides int the wcf service library project, I would like to know what following code is doing?
<%# ServiceHost Language="C#" Debug="true"
Service="Northwind.Wcf.TerritoriesWcfService"
Factory="SharpArch.Wcf.NHibernate.ServiceHostFactory, SharpArch.Wcf" %>
Even if I remove the above Factory attribute, I can still run the service app project and test the service using WcfTestClient utility.
6) When i run my service and using WcfTestClient If I run a method twice that accesses a repository, then on the second call, I get an ObjectDisposedException.
{"Session is closed!\r\nObject name: 'ISession'."}
I believe the NHibernate Session is getting disposed after the first call. How can reinitialise for each call or should I keep it open? I would like to know the best practice?
7) Also If I run the Northwind.Wcf.Web project and click on TerritoriesService.svc
file on the Directory Listing screen, I get the following error
{"Method 'Generate' in type 'Northwind.Data.NHibernateMaps.AutoPersistenceModelGenerator' from assembly 'Northwind.Data, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' does not have an implementation.":"Northwind.Data.NHibernateMaps.AutoPersistenceModelGenerator"}
I don't understand why is it throwing this error, when i already got the method and the Northwind.Web works fine too.
Awaiting
Nabeel

1) Strictly, you can combine the WCF library and the WCF application
in one assembly. This would mean that you would combine the contracts
and the implementations in one assembly.
If you are using svcutil.exe or Visual Studio (which uses svcutil.exe
in turn) to generate proxy classes for your client, you'd be fine
because the proxy classes are generated from discovery of your
services.
If however, you want to use your own classes for transport, which is
quite common in DTO scenarios and the like, you'd need to reference a
shared library from both the client and the server. If that shared
library would be your combined library/application assembly, the
client would get the application implementation in scope (because it
references the assembly that contains the contracts) and that's really
not something you'd want. The client needs to know as little as
possible about the server, just as much as the contracts expose --
that's what the contracts are for in the first place.
I think it is best practice to separate interfaces/contracts from
implementation anyway because it leads to better separation of
concerns. It's just that most parts of your solution don't need (and
shouldn't) know HOW something is done, just WHAT that something can
do. There are many more advantages over this, such as improved
testability.
2) Taken from the code documentation of ICloseableAndAbortable:
"When implemented by your WCF contracts, they are then interchangable
with WCF client proxies. This makes it simpler to use dependency
injection and to mock the WCF services without having to worry about
if it's a WCF client when you go to close/abort it.".
I think that says it all.
3) The client class is, like the code documentation says, a strongly
typed client proxy. It can be used by clients to talk to the server,
providing a strongly typed class that has members that correspond to
the service operations that can be called on the server.
The advantage of this class is that you don't need to use the
svcutil.exe generated proxy classes. This what they mean by not having
to configure it via WCF configuration. This allows you to ship proxy
classes to your clients so they can immediately talk to your server
instead of generating proxy classes first. It allows for more control
as well, changing the code that is generated by the proxy class is
really not something you'd want to do.
This again is a good reason to put the interfaces/contracts in a
separate assembly because you don't want to ship the service
implementation code to your clients.
4) The service host factory creates a service instance based on the
provided service type. This can come in handy if you want to put the
service code somewhere other than in the code behind file. You'd also
need it if you are using Depency Injection, you'd provide the service
contract interface as the type and the SharpArch.Wcf service host
factory resolves it to the correct implementation class type by means
of the DI framework (Castle Windsor in SA). You can think of this as a
means of getting hold of a service implementation while not caring
about where it actually is coming from.
In this case, the service will run when you remove the factory
attribute, because the default factory is able to resolve the service
type. You're bypassing on stuff like DI and session management though,
exactly that what makes SA valueable.
5) I'll have to skip this one because apparently there is no question number 5 :-)
6) As in the Northwind sample project, you are probably using the ServiceHostFactory that comes with SA. With this service host factory, each created service instance is extended by a behavior that closes the NHibernate session directly after it's called. That okay by itself but chances are that your proxy clients are not managed in a transient way by Castle Windsor. Therefore instances get reused, including the closed sessions they (still) contain. Decorate your client proxy classes with the Transient attribute (Castle.Core.TransientAttribute) and Castle Windsor will create a fresh instance every time a service call is performed.
Apparently, there is a second way to solve this but it requires modification of the S#arpArchitecture code base. See WCF connections which process more than one request fail because the nhibernate session is closed and isn't re-opened. on GitHub.
7) I'm sorry, I seriously have no idea. I might look into this later.

Related

WCF service operations not updated

I´m creating a new WCF service. I initially had only three operations. But after some time I decided to add two more. This operations doesn't appear in the Microsoft test client, neither in the list of operations when I try to add a service reference from my WPF client. Also I tried to comment one of the initial operations. It still apears in the Microsoft test client and can be invoked. I Tried also delete the dlls generated by the service and regenerate again. No luck. There are some kind of "cache" where Visual Studio stores the WCF services libraries that I can delete?
UPDATE: I'm working with the service running in the ASP.NET devolopment server.
You need to understand the order in which things happen.
You change your code, adding methods with [OperationContract] on them, or removing them, or changing their parameters or return values.
You then must build your service, producing a .DLL that contains the changes.
You must then deploy the changed DLL to the server it's going to run on
You must then restart the service (this may happen automatically depending on the server. For instance, IIS will recycle the service when it sees that the DLL changed)
You must then update your client, either the WCF Test Client, or "Add Service Reference", or the equivalent.
This last will have the effect of sending a request to the service for the new metadata or WSDL. Only then can the client see the changes you made to the definition of the service.
I don't know why, but I created a new project and copied the definitions of the operations from the problematic project and the problem is gone. One case more for Microsoft mysteries.
Make sure you are updating the services after adding the new operations.
Also make sure they have the attribute [OperationContract].
One thing we have discovered is that when you deploy the dlls that they must be in the bin, and cannot reside in the debug or release folder.
For me worked: just rebuild the wcf project
Did you close the client connection in client side
as showing your service
class Test
{
static void Main()
{
LocationClient client = new LocationClient();
// Use the 'client' variable to call operations on the service.
// Always close the client.
client.Close();
}
}
SOLUTION HERE :
Make sure your dataContract does NOT contain any enum
(You can use integer instead)
Be sure to reference a project in the solution and not a dll on your disk
Remove your "bin" and "obj" folders
Recompile
In IIS recycle the application pool
In IIS restart your service
In IIS "Browse" your service
=> You got it

Auto-generated WCF proxy class renames request/response classes

I am using Visual Studio 2008 to generate a WCF proxy class for an ASMX service I want to consume.
I have tried using both 'Add Service Reference' is VS and the command line svcutil.exe to generate a proxy from the ASMX service WSDL, but each time it creates an duplicate service method (for each operation) with different request and response classes (that have the digit '1' appended to the end the names).
Does anyone know how to stop WCF creating these duplicate methods with the request/response class names having the digit '1' appended to them?
Many thanks!
In your project folder you might have either of the folders 'ServiceReferences' or 'WebReferences'. Look inside these. If they have any folder of the same name as your service reference delete it. Now add the service reference again. It should work.

Namespace Issue with WCF Data Contract / Design Problem?

I am having multiple Services in my application.i have a datacontract that i need to use in more than 1 service.
Eg: class myCommonClass is being used in 2 of my services service1 and service2
To do this, at a service level, i have a MyApplication.Common library and this library contains myCommonClass. Since both my services have a reference to MyApplication.Common, they can both use it.
My client application has service references to both service1 and service2.
To my client application, service1.myCommonClass is a separate namespace as compared to service2.myCommonClass and therein lies my problem
In my Reference.cs (generated via svcutil - the namespace of BOTH classes is the same i.e.
System.Runtime.Serialization.DataContractAttribute
(Name="MyCommonClass", Namespace="http://A.B.MyCommonClassNamespace")])
However, both of these are in 2 separate reference.cs files and the namespaces in the reference.cs is different due to being part of two separate service references.
Hence, to my client application they appear as two completely unrelated classes.
*Question 1 * : Is there any way that can i indicate to my client application that service1.myCommonClass and service2.myCommonClass are inherently the same class?
*Question 2 * : Is there something inherently wrong with my design here for me to run
into this problem?
No, your design is fine. Instead of adding service reference from Visual Studio, generate the proxy class using svcutil on the command prompt. Create a class library project and add the generated .cs files to it. You can create a batch file and run it in pre build step as well.
Use svcutil as below to generate the proxy class in a single file from service dll (the dll that implements your two service)
svcutil.exe /t:metadata "PATH\service1.dll" "PATH\service2.dll"
svcutil.exe /t:code *.wsdl *.xsd /o:Proxy.cs

slsvcutil.exe Proxy and Interfaces

Is it possible when using slsvcutil.exe to generate a proxy through the command line not to have the proxy file output the Interface in an Asynchronous fashion.
For example, if I have a function "foo()" on the serverside in the Interface, when I generate the proxy using Slsvcutil.exe, it makes two functions in the interface definition in the proxy named "BeginFoo()" and "EndFoo()".
All I want is "Foo()", I don't need the other two methods.
Is this possible? I'm using the proxy with Monotouch which is why I need to use Slsvcutil.exe but don't need the Asynchronous methods.
Thanks!
Turns out the Asynch methods are needed on the iPhone making this a moot question.
You can try to copy the ServiceReference from a Visual Studio Project and use the Interface and write the Servie and ServiceChannel maualy. Like: Monotouch/WCF: How to consume the wcf service without svcutil
But it's without svcutil and need some more work

How to use a WSDL file to create a WCF service (not make a call)

I have an old WSDL file and I want to create a server based on this WSDL file.
The WSDL is generated from a ASMX (I suppose but I am not sure).
How can I achieve this ?
original question where the OP thought he needed to create a client based on the WSDL.
Using svcutil, you can create interfaces and classes (data contracts) from the WSDL.
svcutil your.wsdl (or svcutil your.wsdl /l:vb if you want Visual Basic)
This will create a file called "your.cs" in C# (or "your.vb" in VB.NET) which contains all the necessary items.
Now, you need to create a class "MyService" which will implement the service interface (IServiceInterface) - or the several service interfaces - and this is your server instance.
Now a class by itself doesn't really help yet - you'll need to host the service somewhere. You need to either create your own ServiceHost instance which hosts the service, configure endpoints and so forth - or you can host your service inside IIS.
There are good resources out there if you know what to search for. Try "Contract First" and WCF. or "WSDL First" and WCF.
Here is a selection:
Basic overview of WSDL-First development with WCF and SvcUtil.exe.
WSCF - A free add-in to Visual Studio enabling Contract-First design with WCF
Introduction to WSCF
A walkthrough of using WSCF
The WSCF project page on CodePlex (WSCF is now open source)
Article on how to design "WCF-Friendly" WSDL
Use svcutil.exe with the /sc switch to generate the WCF contracts. This will create a code file that you can add to your project. It will contain all interfaces and data types you need to create your service. Change the output location using the /o switch, or you can find the file in the folder where you ran svcutil.exe. The default language is C# but I think (I've never tried it) you should be able to change this using /l:vb.
svcutil /sc "WSDL file path"
If your WSDL has any supporting XSD files pass those in as arguments after the WSDL.
svcutil /sc "WSDL file path" "XSD 1 file path" "XSD 2 file path" ... "XSD n file path"
Then create a new class that is your service and implement the contract interface you just created.
You could use svcutil.exe to generate client code. This would include the definition of the service contract and any data contracts and fault contracts required.
Then, simply delete the client code: classes that implement the service contracts. You'll then need to implement them yourself, in your service.
Using the "Add Service Reference" tool in Visual Studio, you can insert the address as:
file:///path/to/wsdl/file.wsdl
And it will load properly.