I'm working through the NServiceBus ServiceMatrix tutorial, and am trying to understand:
All defined events will be put in the Contracts project.
All commands will be put in the Internal project.
I'm not tracking the intuition here. Why are commands considered an internal notion? Aren't they part of the public contract that other components would need to know about? Why not define all commands and events in the same 'Contracts' project?
Corey,
The reasoning is that commands should be sent only between components that belong to the same logical service, and not between services. Events can be transmitted between logical services.
Related
We are trying to build a Nservicebus service that can communicated with form and wpf based clients using WCF. I have read that you can inherit from WcfService.
like:
public class ThirdPartyWebSvc : WcfService<ThirdPartyCmd, ThirdPartyCmdResponse>
And then you simple create a endpoint in the app.config and you done like described here. but the problem is that i have to create a endpoint for every command.
I would like to have a single endpoint that excepts any command and returns its response.
public class ThirdPartyWebSvc : WcfService<ICommand, IMessage>
Can someone point me in the right direction? Using Nservicebus for client communication can't be done for us and i don't want to build a proxy like server unless thats the only way to do it.
Thanks
So from what I can gather, you want to expose a WCF service operation which consumers can call to polymorphically pass one of a number of possible commands to, and then have the service route that command to the correct NServiceBus endpoint which then handles the command.
Firstly, in order to achieve this you should forget about using the NserviceBus.WcfService base class, because to use this you must closely follow the guidance in the article you linked in your post.
Instead, you could:
design your service operation contract to accept polymorphic requests by using the ServiceKnownType attribute on your operation definition, adding all possible command types,
host the service using a regular System.ServiceModel.ServiceHost(), and then configure an NserviceBus.IBus in the startup of your hosted WCF service, and
define your UnicastBusConfig config section in your service config file by adding all the command types along with the recipient queue addresses
However, you now have the following drawbacks:
Because of the requirement to be able to pass in implementations of ICommand into the service, you will need to recompile your operation contract each time you need to add a new command type.
You will need to manage a large quantity of routing information in the config file, and if any of the recipient endpoints change, you will need to change your service config.
If your service has availability problems then no more messages to any of your NSB endpoints.
You will need to write code to handle what to do if you do not receive a response message from the NSB endpoints in a timely manner, and this logic may depend on the type of command sent.
I hope you are beginning to see how centralizing this functionality is not a great idea.
All the above problems would go away if you could get your clients to send commands to the bus in the standard way, but without msmq how can you do that?
Well, for a start you could look at using one of the other supported transports.
If none of these work for you and you have to use WCF hosted services, then you must follow the guidance in the linked article. This guidance is there to steer you in the correct direction - multiple WCF services sounds like a pain, until you try to centralize them into a single service - then the pain gets bigger, not less.
I went through many posts but, i did not able to clear my some of basic doubts related to WCF service as follow:
Why should we keep separate class library projects assembly for Service.Contracts and Service.Implementation ?
we can implement one interface multiple times even it in single assembly.
It suppose to create - WCF Application project and maintain interfaces into separate folder and SVC.cs file separately.
Add service reference is not good option as it adds all the schemas into client side.
svcutil.exe is also do same thing. Then, what is the best way to consume wcf service at client side ?
All is explained in this great article - WCF the Manual Way…the Right Way.
Essentially, Add Service Reference and svcutil just lead to client proxies that become out of date over time; and the fact that the solution has multiple types defined for what are essentially the same class.
Update: Since writing this answer I have learnt not to have answers in another castle so I update below:
Essentially, WCF the Manual Way…the Right Way describes that rather than using Add Service Reference, you instead divide your WCF system into separate dlls for:
Contracts
Service implementation
Roll-your-own client proxies
Both the service and client add normal code references (not service references) to the contracts dll.
In this way, the service and client are using the same types (and not code-generated ones in the client) and when the contract changes - both the service and client are forced to update less a compile error appears. No more out-of-date clients.
Setting: I'm developing an intranet tool set for my department, the main point of which is to centrally manage data quality and accessibility, but also to automate and scale some partial-processes.
Problem: I currently have my business logic in a CLR assembly, which is available on my SQL-Server for other CLR assemblies that run automated ETL directly on the SQL-Server. I am also developing an intranet site, which also needs the code information in that business logic assembly, but referencing the CLR assembly code has been working out sub-optimally, in terms of deployment and code maintenance. Also another department has voiced interest in using the code-base and data for their own intranet site.
Question(s): I've read quite a few Q&A(1,2,3,4,...) on SO to this topic, but I find it a very encompassing, so I'll try to ask questions for a more specific case(i.e. a single BL and Data Access code base)
Is a WCF service the solution I want? All my potential service clients run on the same server, is there maybe another way to reference the same code base both in CLR assembly and website projects? I don't need support for different platforms(ex. Java) - everything is .NET(yay for in-house progr!) - is WCF overkill?
Can code from a WCF service be used like a class library, or do I need to program a new way for accessing classes/methods from the service?
Separation of Development, Test and Productive instances?
Can a WCF service be updated while clients are accessing it, or do I need to schedule maintenance windows? When I update the service, do I need to update the client as well in some way?
Can I dynamically set the service reference, like I currently am dynamically setting the database connection string, depending on if StageConfig = dev, test, or prod?
My CLR assemblies are written for .Net 3.5, but the websites for .NET 4.0, will that pose a problem?
What minimum set of .NET service architecture programming do I need to know to accomplish this? I'll learn more about WCF with time, but I need to evaluate architecting effort and weigh it against getting things done(feature requests). Does the MS tutorial get me the desired skill?
I appreciate answers to only single questions, if you feel you know something, I'll +1 whatever helps me get closer to a complete answer.
OK, so you want to make your code enterprise-wide. There are two fundamental problems to talk about when you want to do this, so I'll structure the answer that way:
You have to understand what WCF is all about.
You have to manage your dependencies correctly.
What WCF is about
WCF is a way of doing RPC/RMI (Remote procedure call/remote method invocation) which means that some client code can call code that is located somewhere else through the network.
A callable WCF service is determined by the ABC triplet:
The service specification is implemented as a .NET interface with a "ServiceContract" attribute. This is the Contract ("C")
The "location" of the service is determined by a pair : Address ("A") and Binding ("B"). The Binding determines the protocol suite to be used for communication between client and server (NetPipe, TCP, HTTP, ...). The Address is a URI following the scheme determined by the Binding ("net.pipe", "net.tcp", "http", ...)
When the client code calls a WCF service at a specific Address, with a specfic Binding, and a specific Contract (which must match what the server at the specific Address and the specific Binding is delivering), WCF generates a proxy object implementing the interface of the contract.
The program delivering the service is any .NET executable. It has to generate one or many WCF Hosts, that will register objects or classes that implement the service contract, and asociate each delivered service to a specific Address and Binding. (possibly many thereof)
The configuration can be through the app .config file, in which you will be specifying ABC triplets and assotiate these triplets with a name that you will use in your application. You can also do it programmatically, which is very easy.
WCF does not address your problem of deploying your application, or the configuration of addresses and binding. It just addresses the problem of letting two executables communicate with each other with strongly-typed objects (through a specific interface). Sharing the service configuration is up to you. You may use a shared .config file on a Windows share, or even set up a LDAP server that will deliver all the data you need to find your service (namely A and B).
Managing your dependencies correctly
In your scenario, there are three actors that want to use your WCF infrastructure:
Your SQLCLR assembly, which will be a client.
The intranet site, which will be another client.
The service host, which will be a server.
The bare minimum number of assemblies will be 4. One for each of the aforementioned actors, and one specifying the contract, which will be used by all three actors. It should contain the following things:
The interface specifying the contract.
All types needed by the interface, which will of course be sent through the network, and therefore must be serializable.
There should be nothing more in it, or else, it will be a maintenance nightmare.
Answer to your questions
I hope that my answer is clear. Let's sum up the answers to your questions.
Is a WCF service the solution I want? All my potential service clients
run on the same server, is there maybe another way to reference the
same code base both in CLR assembly and website projects? I don't need
support for different platforms(ex. Java) - everything is .NET(yay for
in-house progr!) - is WCF overkill?
Everything is overkill. WCF is rather easy to use and scales down very well.
Can code from a WCF service be used like a class library, or do I need
to program a new way for accessing classes/methods from the service?
Setting up a WCF on existing code requires only the implementation of an additional class, and some code creating the Hosts which will serve the aforementioned class.
Calling a WCF service requires the creation of a Channel, which is a .NET (proxy) object implementing the interface.
So basically, your business code remains in the same state.
Separation of Development, Test and Productive instances?
WCF does not take care of that. Different environments, different service addresses. You have to take care of this yourself.
Can a WCF service be updated while clients are accessing it, or do I need to schedule maintenance windows?
It depends on your maintenance policy. Kill the serving process and launch the new version is the basic upgrade mechanism.
When I update the service, do I need to update the client as well in some way?
Provided that you manage your dependencies correctly like I sketched in the previous section, you need to update the clients only if the service specification (the interface) changes.
Can I dynamically set the service reference, like I currently am dynamically setting the database connection string, depending on if StageConfig = dev, test, or prod?
You have to manage that, probably by etting Address and Binding for a service programmatically.
My CLR assemblies are written for .Net 3.5, but the websites for .NET 4.0, will that pose a problem?
Provided that you manage your dependencies correctly like I sketched in the previous section, the only constraint will be the minimum CLR version required by the "contract" assembly.
What minimum set of .NET service architecture programming do I need to know to accomplish this? I'll learn more about WCF with time, but I need to evaluate architecting effort and weigh it against getting things done(feature requests). Does the MS tutorial get me the desired skill?
You'll need the result of these exercises:
Make two executables, a client and a server, that will communicate
through a WCF contract located in a separate DLL. The configuration
should be located in the app .config file.
Make two executables, a client and a server, that will communicate
through a WCF contract
located in a separate DLL. The configuration should be determined programatically.
Try to send a serializable class as a parameter to your service.
Try to send a serializable class as a return value of your service.
After that, you'll need to think about the best/cheapest way to share the Addresses and Bindings of your services.
Hope it helps.
I'm starting to design a wcf service bus that is small now but will grow as our business grow so I'm concerned about some grwoing problems and also trying not to YAGNI too much. It's a e-commerce platform. The problem is I'm having too many second thoughts about where to put stuff. I will give a scenario to demonstrate all my questions.
We have an e-commerce website that sells products and ultimately deliveries them. For this we have a PlaceOrder service which, among other parameters, expects an Address object that in this context (our website placing an order) is made of City, Street and ZipCode.
We also do business with partners that use our platform only to sell products. They take care of the delivery. For this scenario we have a PlaceOrderForPartner service that, among other objects, expects an Address object. However, in this context (partner placing an order) the Address object is made of different information that is relevant only to a order placed by partner.
Given this scenario I have several questions:
1) How to organize this DataContracts objects in namespaces and folders in my Solution? I thought about having a folder per-context (Partner, Customer, etc) to keep the services and the DataContracts.
So I would have
- MySolution.sln
- Partner (folder)
- PartnetService.svc
- DataContracts (folder)
- Address
- Customer (folder)
- Customer.svc
- DataContracts (folder)
- Address
Using this way I would have a namespace to place all my context-specific datacontracts.
2) What about service design? Should I create a service for each one that might place and order and create a PlaceOrder method inside it like this:
Partner.svc/PlaceOrder
Customer.svc/PlaceOrder
or create an Order service with PlaceOrderForPartner and PlaceInternalOrder like this:
Order.svc/PlaceOrderForPartner
Order.svc/PlaceOrderForCustomer
3) Assuming that I pick the first option in the last question, what should I do with the operations that are made on the order and common to Partner and Customer?
4) Should I put DataContracts and Service definition in the same assembly? One for each? Everything with the service implementation?
5) How to name input and output messages for operations? Should I use the entities themselves or go for OperationNameRequest and OperationNameResponse template?
Bottom line my great question is: How to "organize" the datacontracts and services involved in a service creation?
Thanks in advance for any thoughts on this!
Besides what TomTom mentioned, I would also like to add my 2 cents here:
I like to structure my WCF solutions like this:
Contracts (class library)
Contains all the service, operations, fault, and data contracts. Can be shared between server and client in a pure .NET-to-.NET scenario
Service implementation (class library)
Contains the code to implement the services, and any support/helper methods needed to achieve this. Nothing else.
Service host(s) (optional - can be Winforms, Console App, NT Service)
Contains service host(s) for debugging/testing, or possibly also for production.
This basically gives me the server-side of things.
On the client side:
Client proxies (class library)
I like to package my client proxies into a separate class library, so that they can be reused by multiple actual client apps. This can be done using svcutil or "Add Service Reference" and manually tweaking the resulting horrible app.config's, or by doing manual implementation of client proxies (when sharing the contracts assembly) using ClientBase<T> or ChannelFactory<T> constructs.
1-n actual clients (any type of app)
Will typically only reference the client proxies assembly, or maybe the contracts assembly, too, if it's being shared. This can be ASP.NET, WPF, Winforms, console app, other services - you name it.
That way; I have a nice and clean layout, I use it consistently over and over again, and I really think this has made my code cleaner and easier to maintain.
This was inspired by Miguel Castro's Extreme WCF screen cast on DotNet Rocks TV with Carl Franklin - highly recommended screen cast !
You start wrong on th highest level.
It should not be "PlaceOrder" service, but "OrderManager". Maybe you want to add more service functions later - like inquiring for orders, cancel orders, change orders - who knows. In general, I would keep the number of "services" (.svc) small and add methods there. Otherwise you end up with a HUGH overhead for using them, in code - without any real benefit.
Why separate between partners and customers? I am sure with 15 minutes of data design, you could break things down to exactly ONE data structure so you could have only one service. If not... make that two methods on one interface, limit by security. But I seriously would NOT like two programs for that. Rather have two address fields - "Address" and "PartnerInfo", and only one can be set (other has to be null), checked in the logic.
Separate out into two projects. Interfaces, data contracts go into a separate project (blabalbla.Api) so that customers can actually get the DLL if they want - at least it makes things a lot easier on your end, you can rely on "shared type", no need to generate the wrappers internally. Allows a lot better testing (as sub-projets dont forget to regenerate the wrappers.... which may lead to errors when testing them).
I always put the implementation into a "blabla.Service" project. Url would be "Services.blabla.com/" in a subdomain (or "api.blabla.com", depends mostly on mood, but lately I am going for api mostly) - separates thigns out from the main website.
I am building a set of WCF services that share common data contracts (or entities if you prefer). These are simple data transfer objects that are decorated with DataContract and DataMember attributes. I am explicitly specifying the name and namespace. In trying to follow the principles of IDesign's recommendation of averaging 12 members per service contract, I am breaking my service project into multiple services.
My data contracts are in a separate assembly that I can provide to our clients if they are using .Net. They can tell their service reference to reuse types in referenced assemblies. However, if they are not using .net and they use 2 services that both use the same entity then they will, I assume, get an ambiguous reference message. I can see this in Visual Studio if I don't reference the data contract dll.
My question is, is there anything I can do in my services, or they can do in a client app to get around having to qualify which proxy the data contract came from?
Nice article that describes how to solve this issue.
Sharing DataContracts between WCF Services
I also tend to keep all my Data Contracts in one assembly which is referenced by multiple services and numerous client apps, which works great but I've never tried consuming the service outside of .NET.
It might be helpful to know what technology they are using to consume the service other than .NET? What is throwing the ambigious reference message?
I happen to have multiple services that share objects on my end. I am not certain why you are having this problem. In my case, I am able to access the objects in this way. . . .
SERVICE1 client = new SERVICE1()
client.CommonLibrary.Address. . .
SERVICE2 client2 = new SERVICE2()
client2.CommonLibrary.Address . . . .
It depends on what tools they are using on the client side. For instance, with Axis2 for Java the wsdl2java tool can share types by using the -u switch.
how can I share proxy objects across multiple Axis2 web service clients?
From my understanding and working with WCF, either one of the data contract used by the client app would not matter as long as the fully qualified name is the same and has the same data members. Internally it just create the object dynamically and reassign those data member property using the public setter.
A better approach I think is to refactor your data contract so that you will put all the common across more than one service into one assembly and refer to them hence you will not have this ambiguious or conflict issues regardless how many services are used by the client app.
We generate our service proxies not through the Visual Studio assistant but by custom batch files calling slsvcutil.exe (as we use Silverlight). There you can specify a namespace mapping using the /n parameter like this:
"C:\Program Files (x86)\Microsoft SDKs\Silverlight\v5.0\tools\slsvcutil.exe "^
http://ServiceUrl/MyService.svc^
**/n:http://youruri.org/CustomerService/DataContracts,CLR.Namespace.CustomerService^**
/n:*,CLR.Namepsace.MyService^
/r:"%ProgramFilesFolder%\Reference Assemblies\Microsoft\Framework\Silverlight\v5.0\System.Windows.dll"^
/ct:System.Collections.ObjectModel.ObservableCollection`1^
/edb^
So all data contracts having the namespace http://youruri.org/CustomerService/DataContracts are generated to the clr namespace CLR.Namespace.CustomerService in the proxy file and so on. Given you have generated this proxy in advance in the same proxy assembly, you can cut this whole namespace out of your second file and everything works fine - we wrote a small tool for the last step. All other contract namespaces will be generated to the CLR.Namepsace.MyService namspace (see the asterisk meaning catch all)
The process is some hazzle to set up because you have to hand craft the batch files, but once this is done it works well.