Wcf - Design Parameter Decision

WCF Service call to multiple rows. How to architecture it?

Well, you could always have multiple service methods:

  • the one you already have, to retrieve a single product, and the price for a single product
  • create a new service method which would take a list of product ID's, and return a list of product objects - or a new DTO (data-transfer object) that holds product and price

This way, you could keep your current users happy, and also do something to make batch requests work more efficiently.

DDD and WCF architecture questions

I know the answer depends on the situation but generally, is this architecture in the right path assuming all layers are needed?

Looks pretty standard to me. Just so you know, layering your architecture adds complexity. Make sure that the application is big enough to take full advantage of the Multi-Layer architecture.

Also, if you are separating the layers by assembly, make sure that they are also logically separated. The point of separating assemblies (inconjuction with logical separation) is that you can separate the development of one project without affecting or modifying the rest of the system.

Where does the injection take place?

In the highest layer, your composition root. In this case your WPF application.

More about composition root.

Should the service layer contain a config file for what repository should be used?

The decision of which concrete repository to use should be done in the composition root, placing the decision in the config file means extra flexibility, but it also means extra complexity. Is there a requirement that you need to do this?

So this means, the service layer references both the repository interfaces in the domain layer and its implementation in the DAL?

Only the repository interface in the Domain. Not the implementation. It doesn't need to. Don't do that.

how do I instantiate the service with an IRepository parameter from UI? I would need to add a reference to the DAL which contains the implementation of the repository? Is that OK or correct?

Yes. Your WPF is your composition root, it needs all the references so it can construct your architecture.

Also, this design also means that the DAL should know about the IRepository interface (because they will implement the interface) as well as the Service Layer who will use the repository implementation.

Why would the DAL reference the service layer? it doesn't need to. Don't do that.

But my repository interfaces are in the domain layer; the DAL would need to reference the domain layer to get those interfaces which I think is wrong since I'm referenceing upstream. How do I do this?

You are not referencing upstream, please refer to https://stackoverflow.com/a/24241373/1027250

SOA/WCF dissecting the system & service boundaries

With SOA, the hardest part is deciding on your vertical slices of functionality.

The general principles are...

1) You shouldn't have multiple services talking to the same table. You need to create one service that encompasses an area of functionality and then be strict by preventing any other service from touching those same tables.

2) In contrast to this, you also want to keep each vertical slice as narrow as it can be (but no narrower!). If you can avoid complex, deep object graphs, all the better.

How you slice your functionality depends very much on your own comfort level. For example, if you have a relationship between your "Article" and your "Author", you will be tempted to create an object graph that represents an "Author", which contains a list of "Articles" written by the author. You would actually be better off having an "Author" object, delivered by "AuthorService" and the ability to get "Article" object from the "ArticleService" based simply on the AuthorId. This means you don't have to construct a complete author object graph with lists of articles, comments, messages, permissions and loads more every time you want to deal with an Author. Even though NHibernate would lazy-load the relevant parts of this for you, it is still a complicated object graph.

WCF routing based on parameter type

After a lot of reading I found that the service does not dispatch messages based on the Action URI but rather based on an XML element in the SOAP body, which is supported in SOAP 1.1. The solution was to create a custom class to dispatch messages based on an element in the body. This Microsoft Document explains everything in detail. The basic code I used is as follows:

Dispatcher

public class DispatchByBodyOperationSelector : IDispatchOperationSelector
{
public string SelectOperation(ref Message message)
{
XmlDictionaryReader bodyReader = message.GetReaderAtBodyContents();

//By accessing the body the message is now marked as read, thus we need to clone the message so it's left in an unread state
//NOTE: We have to pass in the body reader because if we try to get it again it throws an error
message = CloneMessage(message, bodyReader);

//The element in the body has "Request" appended so we need to remove it to match the method
return bodyReader.LocalName.Replace("Request", "");
}

private Message CloneMessage(Message message, XmlDictionaryReader body)
{
Message toReturn = Message.CreateMessage(message.Version, message.Headers.Action, body);

toReturn.Headers.CopyHeaderFrom(message, 0);
toReturn.Properties.CopyProperties(message.Properties);

return toReturn;
}
}

Custom Attribute

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Interface)]
public class DispatchByBodyBehaviorAttribute : Attribute, IContractBehavior
{
public void AddBindingParameters(ContractDescription contractDescription, ServiceEndpoint endpoint, BindingParameterCollection bindingParameters){}
public void ApplyClientBehavior(ContractDescription contractDescription, ServiceEndpoint endpoint, ClientRuntime clientRuntime){}
public void Validate(ContractDescription contractDescription, ServiceEndpoint endpoint){}

public void ApplyDispatchBehavior(ContractDescription contractDescription, ServiceEndpoint endpoint, DispatchRuntime dispatchRuntime)
{
//We want the operator selector to be this
dispatchRuntime.OperationSelector = new DispatchByBodyOperationSelector();
}
}

Service

[ServiceContract, DispatchByBodyBehavior]
public class Server : IServer
{
[OperationContract]
public Action1Response Action1(Action1Request request)
{
//Do stuff here
}

[OperationContract]
public Action2Response Action2(Action2Request request)
{
//Do stuff here
}
}

Obviously this is very basic version and requires more validation and edge case handling. The linked Microsoft document goes into further detail.

SOA with WCF responsibilities and dependencies

At first blush, it sounds like the design you've walked into might be an SOA antipattern identified in this article: a group of 'chatty services,' a term the authors use to describe a situation in which ...

developers realize a service by implementing a
number of Web services where each
communicates a tiny piece of data.
Another flavor of the same antipattern
is when the implementation of a
service ends up in a chatty dialog
communicating tiny pieces of
information rather than composing the
data in a comprehensive document-like
form.

The authors continue:

Degradation in performance and costly
development are the major consequences
of this antipattern. Additionally,
consumers have to expend extra effort
to aggregate these too finely grained
services to realize any benefit as
well as have the knowledge of how to
use these services together.

Why would a WCF Contract include a ref/out parameter?

Is there a good reason for having an out parameter instead of adding it to the response?

Not in a web service contract. Maybe laziness and unwillingness to define an additional data contract to be used as return type have been the driving forces behind this design decision. out, ref are .NET specific artifacts. A good and interoperable service contract shouldn't rely on language specific artifacts.

Where should I put Comparers in an app that uses WCF?

Remember that data transmitted over WCF (or via any sort of SOAP-based service) are messages only. They carry no behavior (it wouldn't be interoperable), so all your nice behavior will be lost in translation.

This means you really only have one option: Your business logic must reside in the service, as it can't reside on the client.

That said, there are a few ways you can share code between service and client, but unless you are using WCF purely as a communications stack, it is not recommended, as it will tie client and service together, and make it close to impossible to vary those two independently (let alone let new clients use the service).



Related Topics



Leave a reply



Submit