I am working on a E-commerce system. I use entity framework in my data layer. You can see my request-response cycle in the picture below. In my business layer, classes are page-based. I mean, business classes are created according to the requirement of page.
Do I need surrogate classes? I don't hide any fields of entities and only one entity's fields appears in large quantities.
Will surrogate classes help me to improve response time?
One more question. Should I use WCF in this case? I use WebService in my application.
To answer your 3 questions:
No, doesn't sound like it.
No, a surrogate is used to change type serialisation.
Depends on your requirements.
You should structure your business logic based on the logic itself and it's complexity, not necessarily a class per page. This is not necessarily bad if it makes sense.
It's hard to give you advise based on that abstract and high level diagram. What does your code look like?
WCF can provide a web service. You can use WCF if you want to. What kind of Web Service have you currently got?
I assume you mean Data Contract Surrogates
Use if you need to change how a type is serialised.
Related
I want to know the right concept about it. If I have a MVC application with Repository Pattern, where the BL should be?
Should it be inside the Model? Model should have all the business
logic before call the unitofwork to insert or not the data into
database?
Should it be in the controller? Before call the model?
Should I have a service layer to do the business logic and decide if
I should call the Model to call the UnitOfWork to save the data?
A good explanation will help a lot too.
The short answer - it depends. If it's a fairly complex or sizable application, I like to create a service layer project with the repositories as dependencies. If it's a small application, I'll put the logic in the controller. In my opinion, if it takes more time and effort to create the service layer than it would be to create the application (i.e. one or two controllers), then it doesn't make sense to me to go that route. You also need to consider the likelihood that the application will grow. What might start small could grow into something much bigger and in that case, again, it might be more beneficial to create the separate service layer.
The third one... and then some.
Your application structure could look like this (each in different projects):
Data storage layer (e.g. SQL database)
ORM (e.g. NHibernate or Entity Framework)
Domain (including abstract repositories and entities)
Service layer (and optionally business)
MVC application (which has it's own models relating to the entities)
but there are many ways to go about this depending on the complexity and size of your application.
There is no "correct" answer to this question, it is primarily opinion-based. You can read about my opinion in the following project wiki:
https://github.com/danludwig/tripod/wiki/Why-Tripod%3F
https://github.com/danludwig/tripod/wiki/Dependency-and-Control-Inversion
https://github.com/danludwig/tripod/wiki/Tripod-101
https://github.com/danludwig/tripod/wiki/Testing,-Testing,-1-2-3
https://github.com/danludwig/tripod/wiki/Command-Query-Responsibility-Segregation-(CQRS)
Another piece of advice I would like to offer is never put any business logic in viewmodels or entities. These classes should not have methods, only properties to contain data. Separate your data from behavior. Use models for data, and other types for behavior (methods).
I'm consuming a SOAP web service that creates a separate service point and WSDL for each of its customers. I don't know why the do that. But e.g. if they have two clients A and B, the service designates two different service addresses with different WSDL addresses. These separate WSDLs are 90% the same objects and same functions but some of them are different based on the type of the customer. Therefore the created objects are eventually not the same even though they work exactly the same way.
So in order to fetch the correct service, I store the name of the customer somewhere on a table ("A" or "B") and my program has to know which customer its dealing with every run. I don't want to have different programs for each customer. I just want my program to get the customer name and based on that understand which model and which controller functions it will use.
What is the design pattern(s) that will help me facilitate this issue?
Chances are, in the future there will be an additional customer, so I want my code to be as loosely-coupled as it gets.
I have always wanted to use design patterns correctly in my code so I guess it's time to do so. Should I use a Strategy Pattern? Can you briefly explain what is the best solution for this?
I would use two design patterns in your case. The first one would be the Facade pattern. Use the facade pattern to simplify the interface of the web services your application has to deal with. Make sure you only need to change the implementation of the facade when the webservice contract changes. Convert the objects from the service into objects under your control and call functions with names and parameters that fit your domain and abstraction level.
The second design pattern would be the Adapter pattern. In your case, you should determine if you can decide on a common interface for both web services. So, if the 10% difference between the two services can be converted into one interface (of objects and/or functions) you use in your application.
The facade would use adapters to convert the 10% difference into common objects and functions. After that, the facade uses the common objects and functions, as well as the other 90% of the web services, to supply a proper abstraction layer for your application.
If there are additional customers in the future, you'll most likely only need to add or modify an adapter.
We are writing some support applications (rather small) to our ERP system.
Thus until now I am feeling that I am using the Data Access Layer for 2 roles: the business layer AND the data access one.
I am having trouble deciding what I have to move to a separate layer and if I need to. I have read somewhere that knowing when to make layer separation is wisdom and knowing the patterns is just knowledge. I have neither in adequate amounts.
So I need some help to determine what is what.
My current DAL deals with fetching the data and applying basic logic on them. For example there are methods like
GetProductAvailabilitybyItem
GetProductAvailabilitybyLot
etc.
If I needed to separate them what I would have to do?
One other matter that is in my head is that in order to normalize my DAL and make it return different entities every time (through one general get method) I would have to use DataTable as return type. Currently I am using things like List<PalletRecord> as return types.
I feel that my apps are so small that its hard (and maybe useless) to discriminate these 2 layers.
My basic need is to build something that can be consumed by multiple front-ends (web pages, WinForms, WPF, and so on).
Additional Example:
Lets talk some barcode. I need to check if a fetched lot record is valid or not. I am fetching the record in DAL and produce a method returning bool in business layer?
Then i can call the bool method from whatever presentation in order to check if a textbox contains a valid lot?
Is this the logic extremely simplified?
Based on your description, you should definitely separate both layers right now, when the application is still small. You might feel a BL is useless when you're just accessing and displaying data, but with time you'll find the need to modify, transform, or manipulate the data, like coordinate object creation from different tables, or update different tables in a single action from the user.
The example you provided helps to support this idea, although is quite simplified.
Pablo's answer does offer some good design ideas too: you should definitely use an ORM to simplify your DAL and keep it very thin. I've found NHibernate and Fluent make a very good job on this. You can use the BL to coordinate access using Data Access Objects.
Given that you are dealing with very small applications, why not just have an ORM provide all data-access for you and just worry about the business layer?
That way you don't have to worry about dealing with DataTable's, mapping data to objects and all that. Much faster development, and you would reduce the size of the codebase.
For example, NHibernate or Microsoft's Entity Framework
Now, if you will be providing data to external consumers (you are implementing a service), you may want to create a separate set of DTOs that go through the wire, instead of trying to send your actual model entities.
I am not a big fan of nTire architecture and have some good reasons for it.
Main objective for such an architecture are
Ability to work with different underlying database separation of
context - i.e. application design and business logic Uniformity and
confirmation of best patterns and practices.
However, while doing so, you also make some sacrifices such as give up provider specific optimizations etc.
My advise is, you can go with two layer architecture,i.e. Data access and business logic layer and GUI or presentation layer. It will still allow you to have a common code for different platforms and at the same time will save you from spaghetti code.
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).
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.