WCF - way of using data contracts - c#

If I have a core class which is used internally by all the modules and then I would like to publish a wcf service which would make use of this class... then what is the best way to do that? Is it better to mark it as data contract directly, or better create a new class as data contract which either inherits or maps to the core structure or ... what do you suggest guys?

Either will work, since in most cases the client will be getting a WSDL/MEX representation - not your type directly. In either case, remember to use explicit [DataContract]/[DataMember] attributes so that it truly is contract-based, rather than looking at the fields.
(note: don't inherit a DTO from your domain type; a DTO should be separate, if you go that route)
Personally, I prefer a separate DTO, but I know people have success exposing the domain model directly (that is how LINQ-to-Data-Services works, for example).

Related

Pattern Help: Passing Object from DAL to Contract. Two Classes, One Interface

I have many projects in my solution representing the different layers of the application. The Data Access Layer (DAL) has a model of the database in it and more importantly --for my issue-- a Plain Old Class Object (POCO). I want to send an instance of this POCO to an external requester via a WCF contract. As you know, I must define the Operations Contract and Data Contract at the contract layer. It is here were my problem lies, how do I declare the data contract and its data members when the POCO is situated in another layer?
I have tried defining an interface and have both classes implement it, but I come up against a problem when I am getting the objects from the database and then passing them through the contract, the contract does not know the object being passed to it - even though it shares an interface.
Anyway, hope that is clear (as mud!), and if anyone can advise me on a suitable solution I would be much obliged.
P.S. Using C# in VS2015
Looks to me like what you need is another class specifically built for the WCF layer that contains all the properties and attributes you need to use and then use something like AutoMapper to copy to contents across to your WCF object.
Making use of the Factory Design Pattern could also be of helper here.

Attributes against POCO objects

I have my POCO objects in a separate class, with each one implementing interfaces etc, which i believe perfectly fine to do with a POCO object.
I read all over the place that it is bad practice to add Entity Framework attributes to your POCO objects, so instead i use the fluent API. Again i believe this to be correct.
I gather that if you need to apply a custom attribute against a POCO object, then this is not bad practice is it? I guess its just like adding the object to an interface. Or have i got it all completely wrong?
Using code first approach
POCO objects have not dependencies on external libraries. These dependencies could come with the necessity to use external attributes or to derive from external class/interface.
So, nothing wrong with attributes in themselves, it's more about keeping your models clear from external dependencies. If you depend on external libraries in your models, you have to pull them with your models every time: e.g. when you decide to move your models in separate project, or when you decide to write Unit-tests that touch your models etc.
I agree with Ben Robinson that it is a design choice, but if you have chance to use clear models I think you should use it(with EF you have that chance). And if you were talking about your own custom attributes, then it's OK whatsoever.

Prevent WCF exposing my whole class?

I've just begun learning WCF, and I'm coming from a total non-web background.
I have built a 3-tier desktop application, which compiles into one exe, which runs locally.
Now I want to move the whole business logics layer to a centric server, and make the GUI a client application.
As far as I understand, WCF should be my solution, as indeed, it helped me achieved what I wanted.
I mange to run remote functions, which is the basic of what I need.
My problem now, is that I don't quite understand the architecture.
For example, one of my services, returns a data type (class), from my Business Logics layer.
This class automatically becomes available to the client through the WCF mechanism.
But the problem is, this class contains some methods, which i definitely do not want to expose to the client.
For example a Save method (saves to the db).
Further more, sometimes I don't even want to allow the client to change all the properties of the class, since this class might be sent to one of my services.
I do not want to re-validate the class instance in the service.
What should I do? Should I build another layer, restricted version of the Business Logics, which I expose to the client? Or is there any way expose only part of my class to the client, without restricting the server it self?
I know this is a basic question, but honestly i've searched a lot before asking here. My problem is I don't quite know what to search.
My second question is then, do you have any recommendation for any resource that can explain me this architecture...?
Typically, if you want to encapsulate your business layer, you would not want to expose the business objects directly. This is because you now have a de-coupled client and you don't necessarily want to have to update the client every time the business logic/properties change.
This is where Data Transfer Objects (DTO) come into play nicely. Usually, you want to have control over your contract (data and methods) that you expose. Therefore, you would explicitly make other objects (DTOs) that make up the transfer layer. Then, you can safely change your client and server code independently (as long as both still fulfill the contract objects).
This usually requires a little more mapping (before you send or receive on each side) but it is often worth it.
For WCF, your interfaces and classes marked with [ServiceContract] and your classes marked with [DataContract] usually make up this transfer layer.
In WCF to expose method to client you have to mark it with OperationContractAttribute. So if you don't want clients to use your Save method, just don't mark them with with this attribute.
More info here: http://msdn.microsoft.com/en-us/library/system.servicemodel.servicecontractattribute.aspx
Pretty much same thing with properties, but different attribute: DataMemberAttribute. If you don't wont client to see it, just don't mark them with it (DataMember attribute)
But the problem is, this class contains some methods, which i definitely do not want to expose to the client.
Are you able to provide an example of your class and interface code? If so I'm sure you might be able to get more specific answers.
For example a Save method (saves to the db).
One possible approach would be to separate your class into 2 classes. Define the properties in the first class and then use that class as the base class of your second class. Then use the second class to define the methods. This would allow you to return only the properties while allowing you to keep your code DRY.
Further more, sometimes I don't even want to allow the client to change all the properties of the class, since this class might be sent to one of my services.
I do not want to re-validate the class instance in the service.
While you are able to define logic in the get and set methods for each property I would highly recommend revalidating any input received between services simply because any future changes or errors in one service could potentially lead to larger problems across your application. In addition this also helps to ensure your application is more secure against any potential attacks.
Should I build another layer, restricted version of the Business Logics, which I expose to the client? Or is there any way expose only part of my class to the client, without restricting the server it self?
I agree with the above answers that you should be able to limit access to the different properties and methods using the data and method attributes within your interfaces.
My second question is then, do you have any recommendation for any resource that can explain me this architecture...?
If you are looking for inexpensive but highly valuable video based training I've found the courses that Pluralsight offers to be quite good for both architecture as well as WFC services (btw, I am not associated with them, just enjoyed their training).

Transferring user types between domain and service layers in WCF - suggested approaches?

The problem is familiar - when marshalling user defined / domain types through service boundaries, do we simply annotate rich domain objects with [DataContract] attributes (thereby polluting the domain with ServiceModel constructs), or do we implement some sort of DTO process (creating extra work for arguably little benefit)?
How are people resolving this conflict? Are there other approaches that have fewer downsides?
If you're using the DTO approach, how do you go about implementing the transfer of property values from domain object to DTO?
Thanks
You have mostly answered your questions. If you want very clear design use DTO. If you don't want to add additional layer of complexity either mark classes with DataContract / DataMember attributes or use defalut serialization (only .NET3.5 and newer) which takes all public properties (with getter and setter) + you can remove some properties from serialization by using IgnoreDataMember attribute. To map domain objects to DTOs and DTOs to domain objects you can use AutoMapper.
If you use DTO (my suggestion), you can transfer information from DTOs to entities and vice versa using the assembler pattern. You can do it manually or you can use tools. AutoMapper is a good suggestion.
This may be obvious, but I want to add to what Ladislav has said. Like he mentions, you can use POCO types, but you also have the flexibility to go beyond and use IXmlSerializable, ISerializable, Serializable, and more; these other serialization moels do not have the flexibility of being used with IgnoreDataMember.
See this blog post for more information. It also details how DataContractSerializer would prioritize two conflicting programming models on the same type.

Resolving a call-chain anti-pattern

I've begun to notice something of an anti-pattern in my ASP.NET development. It bothers me because it feels like the right thing to do to maintain good design, but at the same time it smells wrong.
The problem is this: we have a multi-layered application, the bottom layer is a class handling calls to a service that provides us with data. Above that is a layer of classes that possible transform, manipulate, and check the data. Above that are the ASP.NET pages.
In many cases, the methods from the the service layer don't need any changes before going on the view, so the model is just a straight pass through, like:
public List<IData> GetData(int id, string filter, bool check)
{
return DataService.GetData(id, filter, check);
}
It's not wrong, nor necessarily awful to work on, but it creates an odd kind of copy/paste dependency. I'm also working on the underlying service, and it also replicates this patter a lot, and there are interfaces throughout. So what happens is, "I need to add int someotherID to GetData" So I add it to the model, the service caller, the service itself, and the interfaces. It doesn't help that GetData is actually representative of several methods that all use the same signature but return different information. The interfaces help a bit with that repetition, but it still crops up here and there.
Is there a name for this anti-pattern? Is there a fix, or is a major change to the architecture the only real way? It sounds like I need to flatten my object model, but sometimes the data layer is doing transformations so it has value. I also like keeping my code separated between "calls an outside service" and "supplies page data."
I would suggest you use the query object pattern to resolve this. Basically, your service could have a signature like:
IEnumerable<IData> GetData(IQuery<IData> query);
Inside the IQuery interface, you could have a method that takes a unit of work as input, for example a transaction context or something like ISession if you are using an ORM such as NHibernate and returns a list of IData objects.
public interface IQuery<T>
{
IEnumerable<T> DoQuery(IUnitOfWork unitOfWork);
}
This way, you can create strongly typed query objects that match your requirements, and have a clean interface for your services. This article from Ayende makes good reading about the subject.
Sounds to me like you need another interface, so that the method becomes something like:
public List<IData> GetData(IDataRequest request)
You're delegating to another layer, and it's not necessarily a bad thing at all.
You could add some other logic here or in another method down the line, that belongs only in this layer, or swap out to having the layer delegated-to with another implementation, so it certainly could be perfectly good use of the layers in question.
You may have too many layers, but I wouldn't say so just from seeing this, more from not seeing anything else.
From what you've described it simply sounds like you have encountered one of the 'trade-offs' of abstraction in your application.
Consider the case where those 'call-chains' no longer 'pass-thru' the data but require some tranformation. It might not be needed now and certainly the case can be made for YAGNI.
However, in this case it doesn't seem like too much tech debt to handle with the positive side effect of being able to easily introduce changes to the data between layers.
I use this pattern as well. However I used it for the purpose of de-coupling my domain model objects from my data objects.
In my case, instead of "passing through" the object coming from the data layer as you do in your example, I "map" it to another object that lives in my domain layer. I use AutoMapper to take out the pain of manually doing it.
In most cases my domain object looks exactly the same as my data object that it originated from. However there are times when I need to flatten information coming from my data object... or I may not be interested in everything that is in my data object etc.. I map the data object to a customized domain object that only holds the fields my domain layer is interested in.
Also this has the side effect that when I decide to re factor or change my data-layer for something else, It does not have to affect my domain objects since they are de-coupled using the mapping technique.
Here is a description of auto-mapper, which is sort of what this design pattern tries to achieve I think:
AutoMapper is geared towards model projection scenarios to flatten complex object models to DTOs and other simple objects, whose design is better suited for serialization, communication, messaging, or simply an anti-corruption layer between the domain and application layer
Actually, the way you have chosen to go, is the reason of having what you have (I am not saying it is bad).
First, let me say your approach is quite normal.
Now, let me go thought your layers:
Your service - provides somewhat kind of strongly-typed access model. What that means is it has some types of arguments, used them in some special types of methods which return again some special type of results.
Your service-access-layer - also provides the same kind of model. So that it takes special kinds of arguments for special kinds of methods, returning special kinds of results.
etc...
In order not to confuse, here is what I call special kind:
public UserEntity GetUserByID(int userEntityID);
In this example you need to pass exactly the Int, while calling exactly the GetUserByID and it will return exactly the UserEntity object.
Now another kind of approach:
Remember how SqlDataReader works? not very strongly-typed, right?
What you call here for, in my opinion, is that you are missing some not-strongly typed layer.
For that to happen: you need to switch from strongly-typed to non-strongly typed somewhere in your layers.
Example:
public Entity SelectByID(IEntityID id);
public Entity SelectAll();
So, if you had something like this instead of the service access layer, then you could call it for whichever arguments you wanted.
But, that is almost creating an ORM of your own, so I would not think this is the best way to go.
It's essential to define what kind of responsibility goes to which layer, and place such logic only in the layer it belongs to.
It's absolutely normal to just pass through, if you don't have to add any logic in particular method. At some time you might need to do so, and abstraction layer will pay off at that point.
It's even better to have parallel hierarchies, not just passing the underlying layer's objects up, so each layer uses it's own class hierarchy, and you can employ something like AutoMapper in case you feel there's no much difference in the hierarches. This gives you flexibility, and you can always replace automapping with custom mapping code in particular methods/classes, in case hierarchies do not match anymore.
If you many methods with almost the same signature, then you should think of Query Specification pattern.
IData GetData(IQuery<IData> query)
Then, in presentation layer you can implement a databinder for your custom query specification objects, where a single aspnet handler could implement creation of specific query objects, and passing them to a single service method, which will pass it to a single repository method, where it can be dispatched according to a specific query class, possibly with a Visitor pattern.
IQuery<IData> BindRequest(IHttpRequest request)
With this to Automapping and Query Specification pattern, you can reduce duplication to a minimum.

Categories