Background
I've been killing some neurons lately with this. I would like to make a multi-tier application for parcel services like UPS and such. Long story short, the backend will be a WCF-based server while the consumer will be an ASP.NET MVC application. The idea is that the backend will handle all business operations (like adding a new shipment, editing existing shipments, carriers and such) but will provide the consumer with data in form or queries.
And the Issue Is...?
My plan for business operations is that the consumer should pass all the information required to complete the operation (pretty much like a model, i.e. for adding shipments, the consumer would send all the required information for those shipments.) Now, my actual issue is with data querying.
The consumer application should be able to display the backend-provided data in anyway it desires, not limited by a DTO. For example, when listing shipments, I only want to show a grid with Name, ID, date shipped and such, not the entire shipment object graph.
How can the consumer application specify the data projection it needs to the WCF endpoint?
Options
I thought on creating several operation method overloads exposing different DTOs for different purposes. I.e.:
IList<ShipmentDetailsDTO> GetAllShipmentsAsDetailed();
IList<ShipmentListingItemDTO> GetAllShipmentsAsListingItems();
I dropped the idea since the backend is adapting to the consumer application needs, and this is not a good practice. The backend should be agnostic of the consumer.
Another option is to combine WCF data services for querying data and WCF regular services for business operations. This way the MVC application can project the data like a regular LINQ query against the WCF data services. Sounds quite elegant but I would like to hear a second opinion.
Any thoughts? What would you do if you were me? I need an elegant and practical solution for this.
Related
So I've this Microservice architecture where there is an ApiGateway, 2 microservices i.e., Configurations. API and API-1. The Configuration. API is mainly responsible to parse the JSON request and
access the DB and update Status tables, also to fetch required data, it even adds up more values to the JSON request and send it to the API-1. API-1 is responsible to just generate report based on the json passed.
Yes I can merge the configurations. API to the API-1 and make it a single service/container but the requirement is not to merge and create two different components i.e., 1 component purely based on
fetching the data, updating the status while the other just to generate the reports.
So here are some questions:
: Should I use gRPC for the configuration.API or is there a better way to achieve this.
Thank you.
RPC is a synchronous communication so you have to come up with strong reason to use it in service to service communication. it brings the fast and performant communication on the table but also coupling to the services. if you insist use rpc it is better to use MASSTRANSIT to implement the rpc in less coupled way. however in most cases the asynchronous event-base communication is recommended to avoid coupling (in that case look at CAP theory, SAGA, circuit breaker ).
since you said
but the requirement is not to merege and create two different
components
and that is your reason and also base on the fact
also to fetch requried data, it even adds up more values to the JSON
request and send it to the API-1
i think the second one makes scenes more. how ever i cant understand why you change the database position since you said the configuration service is responsible for that.
if your report service needs request huge data to generate report you have to think about the design. there is no more profile on you domain so there cannot be an absolute answer to this. but consider data reduce from insertion or request or some sort of pre-calculation if you could and also caching responses.
I'm rearchitecting a large web forms ASP.Net application, inserting a service layer to take away unwanted responsibility from the presentation layer.
I've seen a lot of examples where all the service methods are contained in one class.
Is this common / best practice? Or is it perfectly feasible to have a number of service classes within the service layer? I'm leaning towards having more than one service and those services being able to talk to each other.
Any guidance, pros/cons?
Richard
P.s. Note that I'm not talking about a web service layer, WCF or otherwsie, although that might become more relevant at a later date.
The SOLID principles, specifically the Single Responsibility Principle would suggest that having all of your functionality in one object is a bad idea, and i tend to agree. As your application grows the single class will become difficult to maintain.
Your comments to Yuriys answer would suggest you want to use an IOC container. Lets consider that in more detail for a moment...
The more functionality this single class contains, the more dependencies it will require. You could well end up having a constructor on the service that has a long list of parameters, simply because the class covers a lot of ground and depends on other functionality at a lower level, such as logging, database communication, authentication etc. Lets say a consumer of that service wants to call one, and only one specific method on that class before destroying the instance. Your IOC container will need to inject every dependency that the service could 'possibly' need at runtime, even though the consumer will only use maybe 1 or 2 of those dependencies.
Also from an operational perspective - if you have more than one developer on the team working on the service layer at the same time, there is more possibility of merge conflicts if you are both editing one file. But, as suggested you could use partials to counter that issue.
Usually a dose of practicality alongside a well known pattern or principle is the best way forward.
I would suggest researching Service Orientated Architecture if you havent already, as it may help you answer some key decisions in the approach to your solution.
Of course, it can.
Moreover, I believe that would be better to extract from this God service layer class few interfaces by functionality (i.e. ISecurityService, INotificationService etc.) and implement each interface in separate project. Also, you can utilize some IOC container to resolve class that implement service's interface. This way you can change each service's implementation independently without changing client functionality.
At least, for the first time you can mark your service super class as partial, then split it up by functionality into few .cs(.vb) files with meaningful names and group them together in Visual Studio. This will simplify navigating across service methods.
My take on structuring an application would be to start with splitting the application into two projects AppX.Web (UI logic) and AppX.Business (business logic), but still keep them in the same VS solution. The clarify in structure between business logic and UI logic helps you understand what services are shared among multiple web pages and which are local to a singel web page. You should avoid reusing code directly between the web pages, if you find that this is necessary then you should probaly move that piece of shared code to the business logic layer.
When implementing the business logic project you should try to create separate classes for different type of business logic. These classes can of course talk to eachother, but do avoid having the web pages talk to eachother.
Once you have separated UI logic from business logic you can continue to break down the AppX.Business code into smaller pieces if necessary. Common examples include:
AppX.Data: A Data Access Layer (DAL) which isolate all data manipulation from the actual business logic
AppX.Dto: Data Transfer Objects (DTO) which can be useful in many scenarios, e.g. when sending data to the client browser for processing by jQuery
AppX.Common: Shared logic which is generic to many other applications, this can be helper classes you have previously created or things which should be reviewed after the project for inclusion in company wide support classes.
Finally, let's talk about going all-in and expose your business logic as a WCF service. In that case you actually need not change anything in the existing structure. You can either add the WCF service to your existing AppX.Web project or expose them separately in AppX.Service. If you have properly separated business logic from UI logic the WCF layer can be just a thin wrapper around the business logic.
When implementing the WCF service it is quite possible to do all of that in a single class. No real business logic is available in the WCF service as it just make direct calls to the business logic.
If you build a new application you should consider you overall design up front, but now that you are rearchitecting I think you should work step-by-step:
Start by creating the AppX.Web and AppX.Business Projects
Identify services and create classes in AppX.Business for those services
Move code from the AppX.Web project into the new classes in AppX.Business, and make sure you call them from the web project.
Continue with additional break-down if you feel you need to do so!
I'm wondering which is better approach from performance point of view, is it better to use one web-service method to load data by passing Database Table name and keys or is it better to use separate method for each database table! knowing that i'm using .net asmx through ajax requests.
it's obvious that one method is better from OO perspective since it have one function type 'data loading' but what about performance? does IIS affected by that or not? also is it better to make multi web-services 'asmx files' or just one!
I really dont think that creating separate methods for handling data fetch different tables is necessary. The performance gain\loss that u r likely to experience by passing an additional table name param to your webservice call would be too small to even consider unless your table names are really huge, which i dont think is the case.
The only reason i would even consider doing some thing like this is if i have nothing else to do in terms of performance improvement or if being forced to do it ;-).
If you really want to optimize your request size try
serializing your input params using JSON (if you are not doing it already)
use a cookieless domain for your webservice
hope this helps
I don't think the service level should have any knowledge of database tables, just like you ideally don't want to see data access code in a controller action or ASPX's code behind.
Personally, I prefer to organize my services to match my domain model.
If I have Customer, Order, and Item classes, for example, I would have corresponding Customer.asmx, Order.asmx, and Item.asmx services to expose selected methods within those classes.
Services are typically responsible for exposing business functionality through a contract. I realize ASMX services really had not concept of "Contracts" in their broadest sense, however you think of it as a set of operations supported by the service. What is your goal here, do you want to expose tabular data as a service ?
Service technology on the Microsoft stack has come a long way from ASMX. Perhaps an obvious question, have you looked at WCF Data Services?
Links:
Exposing Your Data as a Service (WCF Data Services)
Getting Started with WCF Data Services
In an effort to understand MVC 2 and attempt to get my company to adopt it as a viable platform for future development, I have been doing a lot of reading lately. Having worked with ASP.NET pretty exclusively for the past few years, I had some catching up to do.
Currently, I understand the repository pattern, models, controllers, data annotations, etc. But there is one thing that is keeping me from completely understanding enough to start work on a reference application.
The first is the Service Layer Pattern. I have read many blog posts and questions here on Stack Overflow, but I still don't completely understand the purpose of this pattern. I watched the entire video series at MVCCentral on the Golf Tracker Application and also looked at the demo code he posted and it looks to me like the service layer is just another wrapper around the repository pattern that doesn't perform any work at all.
I also read this post: http://www.asp.net/Learn/mvc/tutorial-38-cs.aspx and it seemed to somewhat answer my question, however, if you are using data annotations to perform your validation, this seems unnecessary.
I have looked for demonstrations, posts, etc. but I can't seem to find anything that simply explains the pattern and gives me compelling evidence to use it.
Can someone please provide me with a 2nd grade (ok, maybe 5th grade) reason to use this pattern, what I would lose if I don't, and what I gain if I do?
In a MVC pattern you have responsibilities separated between the 3 players: Model, View and Controller.
The Model is responsible for doing the business stuff, the View presents the results of the business (providing also input to the business from the user) while the Controller acts like the glue between the Model and the View, separating the inner workings of each from the other.
The Model is usually backed up by a database so you have some DAOs accessing that. Your business does some...well... business and stores or retrieves data in/from the database.
But who coordinates the DAOs? The Controller? No! The Model should.
Enter the Service layer. The Service layer will provide high service to the controller and will manage other (lower level) players (DAOs, other services etc) behind the scenes. It contains the business logic of your app.
What happens if you don't use it?
You will have to put the business logic somewhere and the victim is usually the controller.
If the controller is web centric it will have to receive its input and provide response as HTTP requests, responses. But what if I want to call my app (and get access to the business it provides) from a Windows application which communicates with RPC or some other thing? What then?
Well, you will have to rewrite the controller and make the logic client agnostic. But with the Service layer you already have that. Yyou don't need to rewrite things.
The service layer provides communication with DTOs which are not tied to a specific controller implementation. If the controller (no matter what type of controller) provides the appropriate data (no mater the source) your service layer will do its thing providing a service to the caller and hiding the caller from all responsibilities of the business logic involved.
I have to say I agree with dpb with the above, the wrapper i.e. Service Layer is reusable, mockable, I am currently in the process of including this layer inside my app... here are some of the issues/ requirements I am pondering over (very quickly :p ) that could be off help to youeself...
1. Multiple portals (e.g. Bloggers portal, client portal, internal portal) which will be needed to be accessed by many different users. They all must be separate ASP.NET MVC Applications (an important requirement)
2. Within the apps themselves some calls to the database will be similar, the methods and the way the data is handled from the Repository layer. Without doubt some controllers from each module/ portal will make exactly or an overloaded version of the same call, hence a possible need for a service layer (code to interfaces) which I will then compile in a separate class project.
3.If I create a separate class project for my service layer I may need to do the same for the Data Layer or combine it with the Service Layer and keep the model away from the Web project itself. At least this way as my project grows I can throw out the data access layer (i.e. LinqToSql -> NHibernate), or a team member can without working on any code in any other project. The downside could be they could blow everything up lol...
I used to create normal webservices in my websites, and call these services from javascript to make ajax calls.
Now i am learning about Ado Data Services,
My question is:
Does this Ado Data Services can replace my normal webservice in new sites i will create?
And if Yes,
Can i put these Ado Data Services in a separate project "local on the same server" and just reference from my website? "to use the same services for my websites internal use and also give the same services to other websites or services, the same as twitter for example doing"
depends what you want to do , I suggest you read my conversation with Pablo Castro the architect of Ado.Net Data Services
Data Services - Lacking
Here is basically Pablo's words.
I agree that some of these things are quite inconvenient and we're looking at fixing them (e.g. use of custom types in addition to types defined in the input model in order to produce custom result-sets). However, some others are just intrinsic to the nature of Data Services.
The Data Services framework is not a gateway to a database and in general if you need something like that then Data Services will just get in the way. The goal of Data Services is to create a resource model out of an input data model, and expose it with a RESTful interface that exposes the uniform interface, such that every unit of data in the underlying model ("entities") become an addressable resource that can be manipulated with the standard verbs.
Often the actual implementation of a RESTful interface includes more sophisticated behaviors than just doing CRUD over the data under the covers, which need to be defined in a way that doesn't break the uniform interface. That's why the Data Services server runtime has hooks for business logic and validation in the form of query/change interceptors and others. We also acknowledge that it's not always possible or maybe practical to model absolutely everything as resources operated with standard verbs, so we included service operations as a escape-hatch.
Things like joins dilute the abstraction we're trying to create. I'm not saying that they are bad or anything (relational databases without them wouldn't be all that useful), it's just that if what's required for a given application scenario is the full query expressiveness of a relational database to be available at the service boundary, then you can simply exchange queries over the wire (and manage the security implications of that). For joins that can be modeled as association traversals, then data services already has support for them.
I guess this is a long way to say that Data Services is not a solution for every problem that involves exposing data to the web. If you want a RESTful interface over a resource model that matches our underlying data model, then it usually works out well and it will save you a lot of work. If you need a custom inteface or direct access to a database, then Data Services is typically not the right tool and other framework components such as WCF's SOAP and REST support do a great job at that.