Can anyone help, I have 2 applications and they are nearly identical. they have a completely different presentation layer (web) and the business logic and database are nearly identical. Basically one app has some things that the other doesn't.
so i was wondering if i can do the following without breaking any rules etc
Each app has their own presentation layer.
Each app has their own service layer.
Each app has their own data access layer.
Each app shares another service layer.
Hence the shared service layer both apps can access as the business logic is identical, but they both have another service layer which has 5 or 6 methods in there which are specific to that actual app
The data access layer - I don't see anyway of sharing this as there are 2 different db's with entity framework hence its got the EDM in there so its not dynamic - and the tables differ slightly.
I could use IOC on the shared data access layer I suppose
Would anyone help or comment weather this is good practise.. What I didn't want to do is have only a separate service layer when a lot of it is shared..
Is this a good idea? Maybe i have got it wrong, is there a better way?
As Arjen de Blok said, your business entities should use a repository, a repository is an object with methods to query, update or insert domain entities.
The interface which describes your repository belongs to your domain layer, but the implementation belongs to the infrastructure layer (DAL).
You can share the domain and infrastructure libraries between your two projects. If these two projects should retrieves their data through a shared web service or a shared database, you just have to choose (i.e inject) the correct implementation of your repository (your domain objects know only about the interface of your repository, not about the concrete type)
If the business logic is mostly identical then you should focus to this first.
If you want to do DDD then you should identify your entities and (business) services first and place these in a single library.
These entities and business services should talk to your infrastructure layer (your DAL).
If the infrastructure layer is very different in these two applications then try to work with interfaces. So wrap the intfrastructure layer with interfaces and only talk from the domain layer to your infrastructure layer via these interfaces.
To bind your business logic to your infrastructure's implementation you could use IoC/DI.
You could unify the DAL with a Repository interface. You could then implement the interface across projects. You will probably end up with a EF Repository base class as well. You could apply a similar technique to the services, leverage a common interface and then specialize the service implementations.
Related
can you give me some hit or give me explanation how to create Enterprise App in .net, and how projects type use or how should be structure of this projects? I newbie in EE and I read about it, but for me is the best explanation on real world example. My idea about EE solution structure in .net is that:
Data Tier (project type => class library)
database access classes
some mappers (I am not sure if I could use data mapper pattern or else? Is good idea?)
Bussiness Tier (project type => class library)
entities which wil lbe mapped in data mapper in Data Tier
and some application logic
service tier (I am not sure if it should be individual tier, or subtier of bussiness tier - I want to use WCF)
Client (project type => WebForms / Android / WPF / ....)
will be communicate with bussiness tier over WCF
Is my idea good? I will be gratefull for any explanation or hint how patterns could I use with respect my low knowledge. I have requirements to use 2-3 patterns, becouse is school project. Thanks for answers
A implementation I have found quite useful is:
Data Access Layer:
Entity Framework: Unit of Work
Repository Pattern
Business Layer
This layer maps entities and db calls to DTOs
Presentation Layer
Here you present your DTOS using MV? or any other model
There you are using at least 4 design patterns.
For the data layer I would go with repository pattern and unit of work pattern. This is really good way to abstract data layer and create testable code which can be easily unit tested.
Business layer it depends, by DDD business should be encapsulated inside rich data model. Anemic data model is considered as anti pattern. But personally rich model can lead to the ruin of the separation of concern paradigm. Sometimes it is useful to have anemic data model and business layer on top of that model. Like handlers where every handler does exactly one action...
On top of business layer is usually application layer which expose interface to the outside, to your clients. It should be really thin without any business logic in it. Maybe Restful API which will enable you to connect various clients like Android, wpf, Javascript...
Well my application follows DDD design principles. It is an ASP.NET MVC application with the MVC web application being the presentation layer(I moved controllers to application layer though). It also has Application Layer that is primarily application services, use cases, etc. Above the Application Layer is the Domain Layer where Domain Models reside. Then there is Infrastructure Layer, which sits on top of everything else, and is supposed to be dependent on no other layers.
But there is one problem I noticed, that if Persistence Logic goes into Infrastructure Layer as the DDD books suggest, the Infrastructure Layer will have dependency to Domain Layer. The Repositories, for instances, need to know the types of Domain Models(Entities) to create, with this knowledge they become dependent on Domain Layer. The original DDD principles however, suggest that Infrastructure Layer should have absolutely no dependency for anything.
So now I am confused, should Persistence Logic really, belong to the Infrastructure Layer? If so, it makes Infrastructure Layer dependent on Domain Layer. If not, then where should it be? Application Layer? Or maybe a separate layer between Application Layer and Domain Layer(as application services use repositories, repositories use domain models). What do you think?
Types of Dependency
I think an important concept that might assist here is to distinguish types of dependency - specifically, a layer or component can be dependent on another layer because either:
is defined in terms of concepts defined in that layer, or
it uses the other layer - by delegating to that layer (aka calling methods on services in that layer)
Or both the above
Inversion of Control and Dependency Injection make this distinction even more important. They guide that we should depend on abstractions rather than concretions.
This means that, for example, the domain layer can define and depend on an abstraction of a repository - e.g. an IEntityRepository interface.
However, the implementation (concretion) is then implemented in the infrastructure layer.
When the application layer wants to call on the repository, it depends on the abstraction (the interface), and the inversion of control system (IoC Container) supplies it with an implementation from the infrastructure layer.
In this case, the infrastructure layer depends on the domain layer - but only in order to know about the interface it is implementing, but it does NOT depend on any other layer in order to delegate to it - it is the last layer in the call stack.
This concept resolves the conflict you were concerned about, because the infrastructure layer doesn't depend on anything else to carry out it's function.
Onion Architecture
Once you start to incorporate IoC concepts into thinking about your architecture, a model that can become very helpful is the onion architecture pattern. In this view, we retain the layered approach, but rather than thinking of it as a stack, think of it as a layered onion, with the Domain in the centre and the interactions with everything outside the application on the edges.
The original DDD books didn't specifically reference this, but it has become a very common pattern for implementing DDD systems.
It is also known as the Ports and Adaptor pattern, or the Hexagonal Architecture.
The idea is that it models dependencies in terms of 'knowing about' in terms of an onion - outer layers know about inner layers but inner layers don't know about outer layers.
But it models delegation of application flow in terms of movement across the onion - from one side of the onion to the other.
To be more specific:
The outer layer (also known as a 'primary adaptor') is where the request enters the system. The adaptor has the responsibility for handling a specific API presentation (e.g. a REST api) and transforming it into a request to the Application services layer - the next layer in. This is often represented as the top-left of the onion.
The Application services layer represents a 'use case' of the application. Typically a method would use a repository interface to retrieve an instance of an aggregate, then delegate to methods on the aggregate root to execute the business logic that involves changing the state of the aggregate as required for the use case. The application services layer, then uses another interface to ask the infrastructure layer to 'save' changes (often using a unit of work abstraction)
Here we have the application layer delegating control flow to an 'outer layer' of the onion (otherwise known as 'secondary adaptors'). This is often represented as the bottom-right of the onion, and is analogous to the 'infrastructure layer' in your description.
And this is where IoC comes in. Because we have an inner layer delegating to an outer layer, it is only possible because the outer layer has implemented an interface defined in an inner layer (which it can do because it knows about the inner layer). However, the IoC container injects the actual concrete implementation which effectively permits the inner layer to delegate control to the outer layer without being dependent on it.
In this conceptualisation, the request has flowed from the top left to the bottom right without the inner layers knowing anything about the outer layers.
There are 2 options here
1) Work with DAO objects. then the infrastructure layer only needs to know about those DAO objects. Especially if you use Entity framework or something similar then this isn't a bad strategy to follow. You do gain some overhead from mapping but you can use an Automapper for that.
2) live with the fact that the infrastructure knows about your DDD model. But since everything in DDD revolves around your domain model this isn't that bad of a tradeoff. (Especially if your domain model is very well understood and thus doesn't change radically). Be very careful though not to let your domain model be influenced because of database design. It should always be the database who follows, never the domain model where you don't make a certain change because it's hard to migrate in the database.
Persistence Logic usually belongs in the Infrastructure Layer, which is in the outer layer of the onion, and since the outer layers of onions depend on the inner layers, and the Domain Layer is in the center, then yes the Infrastructure Layer depends on the Domain Layer.
In DDD scope, the Persistence Logic should belong to Infrastrure Layer, as detailed persistence implementations are not the concern of Domain Layer.
However, as we think of the architecture of our projects differently, Infrasture Layer could either be dependent on Domain Layer or being depended on by it.
In a traditional layered architecture,
A linear dependency is suggested all the way passed from Presentation Layer, via Application Layer, Domain Layer to Infrastructure Layer.
In this case Infrasture Layer is deemed as an upperstream where both the interfaces and implementations of Persistence Logic are defined.
Domain Layer, as a downstream user, would follow the interface provided by Infrastructure Layer to fetch the entities, convert into domain objects, and then do the domain logic.
Typical codes in java:
// package com.xxxx.product.application
class ProductOrderApp {
private ProductRepository repository;
void orderOneProduct(String userCode, String productCode) {
ProductEntity enitity = repository.getOneByProductCode(productCode);
// 1. convert ProductEntity to Product Object
// 2. pass Product Object to Domain layer to do some logic
...
}
}
// package com.xxxx.product.domain
class Product { ... }
// package com.xxxx.product.infrastructure
interface ProductRepository {
// does not depend on any domain concepts
ProductEntity getOneByProductCode(String code);
}
class ProductRepositoryImpl implements ProductRepository {
#Override
ProductEntity getOneByProductCode(String code) {
ProductEntity entity = ... // get entity from some database
return entity;
}
}
In an onion architecture(as well explained in top answers),
Domain Layer is considered the upperstream, and all other downstream layers should follow the interfaces provided by Domain Layer.
Thus Infrastrure Layer depends on Domain Layer as in it implements the interfaces defined by Domain Layer. Domain Layer does not depend on Infrastructure Layer.
Typical codes in java:
// package com.xxxx.product.domain
class Product { ... }
interface ProductRepository {
// other Domain Logic can easily call this method as it uses Domain Objects for interection
Product getOneByProductCode(ProductCode code);
}
// package com.xxxx.product.infrastructure
class ProductRepositoryImpl implements ProductRepository {
#Override
Product getOneByProductCode(ProductCode code) {
ProductEntity entity = ... // get entity from some database
// persistence logic knows domain objects and do the convertion here
return convertToProduct(entity); // convert to domain objects
}
}
I have a N-Layered Winforms application with 4 layers as follows:
Presentation Layer
Application Layer
Domain Layer
Infrastructure Layer
My Application Layer has a Product Services class which is used for all repository related actions for Products.
Does the interface file for the Product Services class belong in the Application Layer or Domain Layer? I ask because the interface file for my repositories is defined in the Domain Layer even though they are implemented in the Infrastructure Layer.
Thanks in advance.
Service concept can belong to any layer. If you ask for application services, then these should live in the application layer.
In the other hand, if these services are the ones directly accessing the domain, then they're still domain. That is, I would expect to find both a service interface and one or more implementations in any project prefixed with Domain.
BTW, the project has nothing to do with software layers. It's just an organizational unit to group files by some criteria. The most important point is your flow should work with inversion of control in mind to glue layers.
With DDD, is usually recommended to use Dependency Inversion (the D in SOLID), so the tree of dependencies should be
Domain Layer
|
/ \
/ \
Presentation Layer Infrastructure Layer
So the Presentation and Infrastructure "layers" depend on your domain, and not the other way around (the generic version of this is also know as Hexagonal Architecture or Ports and Adapters)
And the Application Layer is indeed part of your domain, as it defines how use cases are supposed to work. I've never used (or seen) an application layer in an application, but what I've done is to put the Application Services in a different package inside the same artefact (the terminology here might be a bit different as I come from a Java background).
I'm having trouble finding an answer to this. Basically, right now I have these layers:
Data Access Layer (where my repositories are). It has Namespace Hello.Data
Business Layer (where my business objects are). It has Namespace Hello.Business
My repositories will return business objects. For example, GetCustomer will return Customer.
However, in my business layer, I also want to add logic that will use the repository to add/update/delete records, so I can reuse those methods in my MVC controllers. This doesn't work though, since I can't have my Data Access Layer reference my Business Layer and also have my Business Layer reference my Data Access Layer. (It creates a circular reference that is not allowed).
What do you guys think is the best solution? Should I put my Business Logic into it's own project?
So instead of:
Hello.Data
Hello.Business
I'll have:
Hello.Data
Hello.Business
Hello.BusinessLogic
Or am I thinking about this all wrong? Thanks!
Why would you separate business logic from business models? The logic should be in the models.
The business logic layer shouldn't have to reference anything, aside from maybe small common utility libraries. Basically, it should have no dependencies on infrastructure concerns (like application technologies, database technologies, etc.). It should contain just business logic.
All other layers should reference the business logic layer.
This doesn't work though, since I can't have my Data Access Layer reference my Business Layer and also have my Business Layer reference my Data Access Layer.
Correct! The mistake in this design is that the business logic layer references the data access layer at all. It shouldn't.
It should, however, contain interfaces for data access (and other infrastructure concerns) which are implemented by the data access layer. The business logic layer only needs to know about the interfaces, it doesn't know or care what implements those interfaces.
A dependency injection container would then be used to connect implementations to interfaces.
The application layer references the dependency injection layer to initialize it and pass the container (which itself implements a generic business logic interface) to the business logic layer.
The dependency injection layer references the business logic layer to know about the interfaces and references the data access (and other infrastructure) layer to know about the implementations.
The data access (and other infrastructure) layer references the business logic layer to know about the interfaces to implement.
The business logic layer doesn't reference anything. It requires a configured dependency injection container and uses that container to get implementations for interfaces.
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.