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.
Related
I've in my Data Layer several REPOSITORY Classes that perform CRUD operations to the DB. I'm not sure about this design since that most of the tables will need a dedicated class per Repository and after a while I'll end up with a lot of REPOSITORIES for each table that exists in the DB. I did this because, of course, I`m still learning C# and because every sample that I see in the Web, a dedicated REPOSITORY per Table is needed, so... I did the same...
(If better options exists, please let me know)
Any way, I`m also learning WCF and from what I have seen so far appears that the implementation design is somewhat similar to repositories in the DataLayer.
In WCF I have an Interface ServiceContract that is implemented by the other Class that exposes those operations.
Here`s my confusion with this, the WCF ProxyClient will use the Operations defined in the ServiceContract to perform calls to the DB, but since that I want to expose the same CRUD operations to remote WCF clients, should I create one class per each Table as I have in the Data Layer REPOSITORIES?
From several examples that saw online, the WCF ServiceContract is more likely to be used for specific Operations, like GetSomething by ID, performThis or That... But those operations are more likely to be performed by the Presentation Layer and Business Layer... And If I use WCF to Communicate Between Business Layer and Data Layer, should I expose CRUD operations in WCF service to proxy clients?
I`m sorry for the long description, but my head is spinning...
Perhaps with your help I can make any sense of all of this...
First you must think in WCF as framework to expose some of your business logic (from msdn):
Service operations enable you to expose business logic in a data service
Then, when you say:
And If I use WCF to Communicate Between Business Layer and Data Layer
That does not make much sense in the most of cases, the best approach is:
Service Layer (WCF) > Business Layer > Data Access Layer.
Here is a good example of this from msdn:
Since you must think in "what" you really want to expose, your code must follow this idea. So, for instance, you have a repository called "Client" that has a couple of methods for CRUD, and some repositories related to "Client" like "ClientType" and "ClientExtraData".
Your service don't need to have the same structure, you can encapsulate all in a "ClientService", that has some operations like "GetClient", "GetFullClient" that returns Client and ClientExtraData, and so on. This is just an example to clarify what I mean.
Same approach as MVC here, your Model for your user interface does not to be same Model from your repository.
Create a service model and use Request and Response patterns in your service.
You can read more about here: http://www.servicedesignpatterns.com/requestandresponsemanagement/datatransferobject
And here: https://msdn.microsoft.com/en-us/library/ee658090.aspx
Hope this can help you design and writting your service layer.
If you are using azure table storage as your table, you can have a single generic repository with a type constraint to implement ITableEntity interface.
Your repository can then internally convert the input entity into a DynamicTableEntity and write it to azure table storage. You can decide which table the entity needs to be written based on entity type or a custom entity property like a domain name etc..
For WCF service contract it is slightly more complex. WCF supports serialization over inheritance. You can have your ServiceContract take a common base class in its Operation Contracts as parameter and/or return value. Then you need to define the actual child classes (the entity classes) via KnownTypeAttribute in your WCF Service Contract explicitly so you can use it to pass your entities back and forth.
This way your architecture will have a common repository for multiple entity types and a common WCF ServiceContract.
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).
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).
I am working on a business layer functionality.
There are two layers :-
1) Entity Data Model Layer which is the logical layer
This logical layer maps to a storage layer.
There are different classes in each of this layer.
The data storage layer has subject, test and result as objects
The logical layer has entity as objects.
I am writing a code which accepts an object of logical layer and converts it to storage layer objects.
It does so by reading the schema of the logical layer.
The schema of the logical layer is stored in an xml file and it has attributes which map to physical layer.
My code will interpret this schema and convert to appropriate physical layer objects.
The class which I have written is as follows :-
DataModelToStorageTranslator
{
IStorageLayerObject TranslateToStorageLayer(ObjectOfLogicalLayer);
}
The different classes of the storage layer are derived from the IStorageLayerObject.
The client will check the type of object at runtime.
Is there a better way to achieve the same ?
My implementation is in C#
Thanks,
Vivek
Unless there is a very good reason for using XML, I would avoid it. If you have a fixed number of objects that will need conversion from logical layer to storage layer I would suggest to create a DataModelToStorageTranslator facade like this:
DataModelToStorageTranslator{
SubjectStore translate(SubjectLogical subject);
TestStore translate(TestLogical test);
ResultStore translate(ResultLogical result);
}
That would give you more type safety as you will not need to check object types and cast. You will need to extend your interface anytime you want to add new objects (which I think is a good way of doing it for smaller projects).
To just copy Properties from the business layer to the DTO you can have a simple reflection based copy algorithm. There are ready-to-go implementation. One suitable should be AutoMapper. There are similar tools around.
Do not map over XML, that is just time consuming and will slow the reactioness of your application.
If you worry about type safety and speed issues in the conversion process consider using automatically created code using T4.
Just my thoughts.
I did something similar to this but used extensions methods on the objects, i just found that way a but more fluent and easy to follow, so i'd have calls like this.
ClientEntity.ToSaveableEntity()
which would return an SaveableEntity object.
Is it good practice to reference my web applications domain layer class library to WCF service application.
Doing that gives me easy access to the already existing classes on my domain model so that I will not need to re-define similar classes to be used by the WCF service
On the other hand, I don't like the coupling that it creates between the application and service and i am curious if it could create difficulties for me on the long run.
I also think having dedicated classes for my WCF app would be more efficient since those classes will only contain the members that will be used by the service and nothing else. If I use the classes from my domain layer there will be many fields in the classes that will not be used by the service and it will cause unnecessary data transfer.
I will appreciate if you can give me your thoughts from your experience
No it's not. Entities are all about behaviour. data contract is all about... data. Plus as you mentioned you wouldn't want to couple them together, because it will cripple you ability to react to change very soon.
For those still coming across this post, like I....
Checkout this site. Its a good explanation on the topic.
Conclusion: Go through the effort of keeping the boundaries of your architecture clear and clean. You will get some credit for it some day ;)
I personally frown on directly passing domain objects directly through WCF. As Krzysztof said, it's about a data contract not a contract about the behavior of the the thing you are passing over the wire.
I typically do this:
Define the data contracts in their own assembly
The service has a reference to both the data contracts assembly and the business entity assemblies.
Create extension methods in the service namespace that map the entities to their corresponding data contracts and vice versa.
Putting the conceptual purity of what a "Data Contract" is aside, If you begin to pass entities around you are setting up your shared entity to pulled in different design directions by each side of the WCF boundary. Inevitably you'll end up with behaviors that only belong to one side, or even worse - have to expose methods that conceptually do the same thing but in a different way for each side of the WCF boundary. It can potentially get very messy over the long term.