I have a business layer that has some business objects/POCOs/entities/whatever. I also have some repositories for the data access. Up until this point, I've been accessing the repositories directly from my UI layer. I'm at a point where I actually need some more classes that aren't straight CRUD, so I'm going to create some business logic classes that will do the logic, and CRUD, and the repositories won't be accessed by the UI anymore (which should probably have been done from the start).
What should I call these classes? The only thing I can think of are service classes, but I have actual WCF services in this application, so that will make it confusing. The WCF services will also be using these classes, so having a service use a service class seems odd and confusing.
I use the "Service" naming convention as well. It's true the "service" has become a very overloaded term in the industry, but it makes the most sense. Developers reviewing the code should be able to determine the difference between a Application/Domain Service vs a WCF service, and while having a WCF service call other service classes may seem confusing, I think you'll find that it isn't. The idea of a service is that it is code that performs a function, and is available for use by other code. It might be an internal service, or it might be a service externally exposed via http or whatever. But the idea of what the code does is the same.
If your 'services' are orchestrating business logic using a number of domain objects, you're likely implementing the Facade Pattern - so perhaps you can name them with this suffix, eg OrderManagementFacade
From your description, it sounds like the WCF classes are actually implementing a service host. I typically name such classes with a "ServiceHost" suffix. It separates them nicely from the actual service classes.
So, for example, you would have your business logic in a class named "CustomerService" and the corresponding WCF class would be named "CustomerServiceHost".
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 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 have the following layers currently in my application:
API
AppService Layer
Domain Model
Repository
The lower (2) layers (domain and repository) offer almost total reuse across business needs so I thought of exposing at least my domain model as a service, possibly a WCF service. Basically the domain entity data, behavior, and persistance are reusable and I need a way to centrally expose this.
I have read the following (Sharing domain model with WCF service) and ones similar that indicate for good reason why not to expose domain entities directly via WCF. Most of the examples indicate to create data contracts to expose domain data and then have mapping mechnisms to map between the domain and DTO (Data Contract) data. So far so good.
If I have a method in my domain layer like below, how do I expose it via the new WCF service? I thought I would only expose DTOs and therefore how do I also expose the shared/common domain behavior I want to reuse across processes?
public int ProcessSomeRule(string param1, string param2)
If the answer is to create a method on the WCF service that acts as a proxy still not exposing the ProcessSomeRule method directly, I'm cool with that but that spawns another question. The purpose of this abstraction and creating a method on the WCF service named for example ProcessSomeRuleWCF(string,string) that just turns around internally and calls the domain method seems to still be coupled and not offer a pure abstraction. It will still be sensitive to signature changes.
I read that by not exposing the methods directly, we can make changes internally without having to modify the contract interface. OK, this sounds great by definition, but if my internal method needs an additional parameter and now has the signature `ProcessSomeRule(string, string, string), guess what? My contract interface method will now break because it's missing the 3rd parameter, so my interface has to change. Not sure how to do this and still make the abstraction worthwhile?
My repository in the same manner is generic and can be used across processes and I want to reuse this layer too. Currently my repository (UoW) Interface is injected into my AppService layer, so I have no idea how this would work if Repository layer was a WCF service.
Question: How do I expose the shared behavior of the domain and repository layers and what would the names of these new layers be called? Is the new layer exposing the domain named 'Domain Service' and sit between 'AppService' and 'DomainModel'?
Lastly, if I'm on the wrong path with any of this feel free to guide me back. Thanks!
How do I expose the shared behavior of the domain and repository
layers and what would the names of these new layers be called?
In the context of a hexagonal (ports & adapters) architecture, your domain layer would be encapsulated by application services thereby defining the core of your application. Application services implement use cases by delegating to aggregates and domain services and orchestrating access to repositories and infrastructural services. Next, you can "adapt" your application to infrastructure. Having a repository implement an repository interface declared in the domain layer is an example of this. The repository implementation serves as an adapter between the domain and the outside world. Similarly for WCF services, usually called open-host services in DDD, they adapt your application to a transport infrastructure. The WCF service, or ASP.NET WebAPI service, would be a relatively thin layer that delegates to application services. Again, the purpose of this layer is only to serve as an adapter. This layer does own the contract that it exposes publicly. In DDD this is referred to as the published language. In WCF, for example, it would be defined via DataContract and DataMember attributes. These contracts are how external systems will access your domain. Having a buffer between published contracts and the internal domain is important because they will likely change at different rates and have different consumer requirements.
Is the new layer exposing the domain named 'Domain Service' and sit
between 'AppService' and 'DomainModel'?
No, a domain service is part of the domain layer itself, sitting along with entities, aggregates and value objects.
I think to expose domain object as service is not difficult. but system is really combination service and UI. UI access service, and service can be implemented on different ways: DDD or database-central . so it maybe not a good idea to tell the service caller how we implement our business logic.
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.
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.