I have been asked to work on a project, based on SOA, using WCF. I have dabbled with WCF (Creating and consuming), but never with SOA. Am I right in saying that a single service would have the usual service layer, business layer and data access layer (if one's needed). The service layer would then expose methods.
Can Service A reference Service B, and service B reference service A?
And then a UI can access these services, via references - and that's essentially SOA? I am battling to find up to date, recent tutorials (Youtube), and the 'guides' I see online seem extremely complicated.
This Wikipedia entry is pretty clear I think?
Lets try a simple example. Say we have Library application that lets you check books in and out.
If you look at the "traditional" non-SOA way to approach n-tier systems then you have a service called MyService that has methods called something like CheckOutBook. This would go away and internally have a Book class and a Person class and would perform say Book.IsAvailable = False and Person.NumberOfBooks.
That is fine, but say you now have another application that wants to work with People. You can't just use the above service because the logic is tightly coupled with what you are doing, i.e. Library transactions. Instead you would have to copy / paste code into a new service "BookShop".
With SOA you would have a Book service and a Person service. The Person service would have an action such as Person.AssociateWithBook that both Library and BookShop could use without having to alter as it is simple enough to do the minimum. It is then down to the application to call the right service(s) to do the job required. This means that it is reusable without needing to modify the various services.
This is very simplistic but hopefully shows the architectural differences and get you going?
I'd skip question about SOA, since each one can call SOA whatever he understand SOA (Service Oriented Architecture) is. I mean, each architecture, using services, can be called SOA...
From technical aspect, I'd build it in next way:
IMO, Services by themselves should have as less logic as they can (like facade pattern), all there logic should be moved down to Business logic.
Service A using ServiceA.BusinessLogic, calls service B (proxy for service B is available for ServiceA.BL).
Same for Service B, calling service A.
This will give you bi-directional communication, without issues of Duplex (broken callbacks, ...).
UI should access the services as well - using UI.BusinessLogic ( I usually prefer think about service communication as sort of Communication Data Access Layer).
Related
I've been reading a lot about dependency injection and the service locator (anti-?) pattern - a lot of it on StackOverflow (thanks guys :). I have a question about how this pattern works when it's within a n-layer architecture.
I've seen a lot of blog posts where they describe injecting a IDataAccess component into the business objects. E.g.
public class Address
{
IDataAccess _dataAccess;
public Address(IDataAccess dataAccess)
{
this._dataAccess = dataAccess;
}
}
However, I was under the impression that in an n-layer architecture, the UI layer should not need to have any knowledge of the data access layer... or even know that there /is/ a data access layer! If DI requires exposing the IDataAccess interface in the constructors of the BusinessObjects, this then exposes to the UI the fact that the Business Layer uses a data access layer under the hood - something the UI doesn't need to know or care about surely?
So, my fundamental question is: Does DI require that I expose all my lower layer interfaces to all upper layers and is this a good or a bad thing?
Thanks
Edit: To clarify (after a few comments), I know my business object should be ignorant of the which specific implementation of which IDataAccess it uses (hence the Dependency being injected in the constructor) but I thought that the layers above the BO should not know that the Business Object even requires a dependency on a DAL.
This is really a fairly complex topic, and there are many ways of doing an n-tier architecture. No one way is "the right way", and how you do it depends on your needs as much as it does your personal preferences.
Dependency Injection is about managing dependencies. If your object should be unaware of any dependency, then you would not write your objet in the way you mentioned. You would instead have some other service or method that would populate the data in an agnostic way. Data doesn't mean "Database" either. So IDataAccess could mean it comes from a database, or it comes from a network socket or it comes from a file on disk. The whole point here is that Address does not choose what dependencies it creates. This is done through configuration at the composition root.
Things need data, otherwise your app is probably useless. Making your Address object load itself, however, may not be the best way to go about things. A better approach may be with a factory class or service method.
I think the answer is rather simple. Your bottom layers (interface, bll, dal, entities) are just a bunch of libraries. It is up to the client to decide which libraries to be used and it will increase client's flexibility. Moreover they are libraries, so any application-related configurations (connection strings, data caching, etc) lies on the client. Those configuration itself, sometimes also need to be injected and included into Composition Root.
However, if you want to has an uniform logic and not client's flexibility, you can choose web/app services as an additional layer.
1st Layer Entities
2nd Layer Interface
3rd Layer BLL & DAL
4th Layer Web/App Services
5th Layer UI
This way, your composition root exists in one layer (4th). And add your UI just need to add service reference to 4th layer (or 1st if needed). However, this implies the same Mark Seeman's article again, layering is worth the mapping. I assume that you can change the app/web service to Composition Root.
Moreover, this (app/web service) design has pros/cons. Pros:
Your app is encapsulated
Your app is being bridged by app/web services. It is guranteed that your UI don't know the DataAccess, thus fulfill your requirements.
Your app is secured
Simply said, having UI need to access app service is a huge gain in security aspect.
Access Portability
Now your app can be accessed everywhere. It can be connected by 3rd party app (other web) without has relying on dlls.
Cons:
Overhead cost during service call
Authentication, network connection, etc, will cause overhead during webservice call. I'm inexperienced for the performance impact but it should be enough for high traffic app.
Inflexibility of client
Client now need to access BLL/Services by using services instead of normal objects.
More Service for Different Type of Client
Now you need to provide more service than needed. Such as WebRequestRetriever, MobileRequestRetriever instead of accessing to a mere IRequestRetriever and let the composition root wire up the rest.
Apologize if this answer boarden the topic (just realized after finished).
IMHO:
It depends on who does the injection !-
It seems you need to/expect to have an MVC or MVP architecture to be in place, where a controller or Presenter does the job of translating the UI calls to business objects ,back and forth -
Creating concrete implementations of IDataAccess, Sending it to Address class.
So that the UI is totally unaware of who is providing the data it needs, and it provides you the expected scalability.
Thanks
Tarriq
I am designing a system and I have read many articles saying don't put business logic in your service code. And only put your business logic in your domain objects.
I am not hosting my service code anywhere and it is directly accessed by my presentation layer. In future, I might want to expose this service code via WCF IIS service.
But I don't understand why services should be light-weight?
What is the advantage of it? When will we ever replace our services? Please explain
The idea is that by having different layers in your application, it makes it reusable. For example, your Business layer may have a function to check out a book. Well you can take that function and have it be called from different layers. A Console app can call it, a service can call it, or a web page can call it.
Additionally, it is easier to test. You can trigger the method in a sample application that just calls your BLL, and you don't have to worry about having your service call it.
In my understanding, this is about adherence to the single responsibility principle. The general idea is that the single responsibility of your service layer should be the translation of service operations to domain operations. I.e. you write a service type which exposes a method representing a service operation with a service contract as an input. The service method translates the service operation to a domain operation, and lets the domain object(s) worry about the business rules. This way your type encapsulates the translation of service operation to domain operation and nothing else.
Note that I am assuming that 'service' code, in the articles you are referring to, refers to the service interface in a service oriented architecture.
Several "parts" (a WinForms app for exmaple) of my project use a DAL that I coded based on L2SQL.
I'd like to throw in several WebApps into the mix, but the issue is that the DAL "offers" much more data than the WebApps need. Way more.
Would it be OK if I wrapped the data that the websites need within a web-service, and instead of the website connecting directly to the DAL it would go through the web-service which in turn would access the DAL?
I feel like that would add a lot of overhead, but on the other hand, I definitely don't like the feeling of knowing that the WebApps have the "capabilities" of accessing much more data than they actually need.
Any input would be greatly appreciated.
Thank you very much for the help.
You can either create web services, or add a repository layer that presents only the data that your applications require. A repository has the additional benefit of being a decoupling layer, making it easier to unit test your application (by providing a mock repository).
If you plan on eventually creating different frontends (say, a web UI and a WPF or Silverlight UI), then web services make a lot of sense, since they provide a common data foundation to build on, and can be accessed across tiers.
If your data access layer were pulling all data as IQueryable, then you would be able to query your DAL and drill down your db calls with more precision.
See the very brief blog entry I wrote on Repository and Service layers using Linq to SQL. My article is built around MVC but the concept of Repository and Service layers would work just fine with WebForms, WinForms, Web Services, etc.
Again, the key here is to have your Repository or your Dal return an object AsQueryable whereby you wait until the last possible moment to actually commit to requesting data.
Your structure would look something like this
Domain Layer
Repository Layer (IQueryable)
Service layer for Web App
Website
Service layer for Desktop App
Desktop App
Service layer for Web Services
Web Service
Inside your Service layer is where you customize the specific calls based on the application your developing for. This allows for greater security and configuration on a per-app basis while maintaining a complete repository that doesn't need to be modified until you swap out your ORM (if you ever decide you need to swap out your ORM)
There is nothing inherently wrong with having more than you need in this case. The entire .NET 4 Client Profile contains over 50MB of assemblies, classes, etc. I might use 5% of it in my entire career. That doesn't mean I don't appreciate having all of it available in case I need it.
If you plan to provide the DAL to developers that should not have access to portions of the data, write a wrapper or derive a new DAL. I would avoid the services route unless you're confident you can accommodate for the overhead.
Sounds like you are on the right track. If many applications are going to use the this data you gain a few advantages by having services with DTOs.
If the domain model changes, just the mapping to the DTO needs to change. You can isolate the consuming application from these changes.
Less data over the wire
You can isolate you applications from the implementation of the DAL.
You can expose different services (maybe different DTOs) for different applications if it is necessary to restrict what parts of the object model should be exposed.
I am moving onto a new team that has implemented a solution using SOA with WCF. The services are all very vertical, for example: a CustomerService, an AddressService, an AccountService, etc. To return the fully populated objects the services may call another service over a wcf endpoint.
There are a few very high level vertical areas, but underneath they can reuse a lot of the core service logic.
How valid is the following new architecture:
The webservices are thin layers that handle remote calls; they are strictly for communication. The real functionality would be implemented in something lets call, "business or domain services".
Domain Service responsibilities:
Reference data access / repository interfaces for working with the infrastructure
Call multiple repository methods to create fully populated objects
Process data against the complex business rules
Call other domain services (not having to call WCF)
This would give us domain services that can be tested outside of specific WCF and SQL Server implementations.
The web services reusing the different business services seems to be the biggest gain and yet the biggest potential pitfall.
On one hand the logic can be reused for multiple services, eliminating web service calling web service calling web service.
On the other hand, if someone changes one of the assemblies multiple services need to be updated, potentially breaking multiple applications.
Have people tried this and had success? Are there better approaches?
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.
That can be a valid approach. The pitfall about updating multiple services depends on how closely related the services are. Do you have a use case where if Customer Service is updated and Address Service is not the clients can still work or is it more common that all services are used by the same client and hence should be updated together. Remember the service only changes if the WSDL changes and not implementation. If you manage not to change the DataContracts and OperationContracts of the front end services there is no worries.
One approach you may investigate is using in-proc WCF services for your domain services. Alternately the front end webservices can use domain managers/engines in separate;y layered assemblies which in turn uses repositories. You can have a coarse grain of webservice class implementations and fine grained managers for domain entities that are mocakble and unit testable.
My Situation:
The data request chain of my application looks like this:
(Client) -> (WebService) -> (SQL or OLAP Cube)
The client is a Silverlight Application that uses a generated proxy to communicate with a WCF webservice. Which in turn does authorization and accesses SQL DB's and OLAP Cubes using a DAL component, basically it just forwards the requests. Therefore, each method exists in four different places:
// WCF Webservice interface and implementation (used by client)
public interface ICatalogService
public class CatalogService : ICatalogService
// DAL interface and implementation (used by webservice)
public interface ICatalogDataAccessLayer
public class CatalogDataAccessLayer : ICatalogDataAccessLayer
Now my question, where should I put documentation to clearly specify these methods? On class or interface level, on the DAL or on the webservice?
My thoughts so far:
I would say it makes most sense to write the method specs on the interface, because it is the contract that is being consumed. However I don't see an advantage between webservice and DAL in my specific situation:
I am the only developer, there is no separate webservice-guy or client-guy that needs the docs
This is a closed architecture, the webservice is not public
Everyone working on this project in the future, will have access to all components of it (and will find the docs, wherever they are)
So, what do you think about it? Where should I put method-level documentation in this case?
I would think that most people would expect a web service to be documented more heavily than a DAL (especially if the DAL is mostly generated code: I'm guessing so as these are pass-through methods). I would add a pointer to the web service documentation in the DAL comments for those who work with it in the future.
The reason is twofold. First, the Web Service is the real point of interaction (and thus the point where more clients might be added, which means having the service documented is a plus). The second is that the DAL really doesn't sound like it provides "added value" over the Web Service (in the configuration described), so pointing back to the real point of interaction and value makes sense.
If the DAL was ever threatened with reuse by another client without the web service layer... obviously that changes things to lean the other way around (or to automate duplicate comments).