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.
Related
I have many projects in my solution representing the different layers of the application. The Data Access Layer (DAL) has a model of the database in it and more importantly --for my issue-- a Plain Old Class Object (POCO). I want to send an instance of this POCO to an external requester via a WCF contract. As you know, I must define the Operations Contract and Data Contract at the contract layer. It is here were my problem lies, how do I declare the data contract and its data members when the POCO is situated in another layer?
I have tried defining an interface and have both classes implement it, but I come up against a problem when I am getting the objects from the database and then passing them through the contract, the contract does not know the object being passed to it - even though it shares an interface.
Anyway, hope that is clear (as mud!), and if anyone can advise me on a suitable solution I would be much obliged.
P.S. Using C# in VS2015
Looks to me like what you need is another class specifically built for the WCF layer that contains all the properties and attributes you need to use and then use something like AutoMapper to copy to contents across to your WCF object.
Making use of the Factory Design Pattern could also be of helper here.
I am trying to learn some concepts about DDD and the part of persisting Aggregates is confusing me a bit. I have read various answers on the topic on SO but none of them seem to answer my question.
Let's say I have an Aggregate root of Product. Now I do not want to inject the ProductRepository that will persist this aggregate root in the constructor of the Product class itself. Imagine me writting code like
var prod = new Product(Factory.CreateProductRepository(), name, costprice);
in the UI layer. If I do not want to inject my repository via dependency injection in the Aggregate Root, then the question is where should this code go? Should I create a class only for persisting this AR? Can anyone suggest what is the correct & recommended approach to solve this issue?
My concern is not which ORM to use or how to make this AR ORM friendly or easy to persist, my question is around the right use of repositories or any persistence class.
Application Services
You are right, the domain layer should know nothing about persistence. So injecting the repository into Product is indeed a bad idea.
The DDD concept you are looking for is called Application Service. An application service is not part of the domain layer, but lives in the service layer (sometimes called application layer). Application services represent a use case (as opposed to a domain concept) and have the following responsibilities:
Perform input validation
Enforce access control
Perform transaction control
The last point means that an application service will query a repository for an aggregate of a specific type (e.g. by ID), modify it by using one of its methods, and then pass it back to the repository for updating the DB.
Repository Ganularity
Concerning your second question
Should I create a class only for persisting this AR?
Yes, creating one repository per aggregate is a common approach. Often, standard repository operations like getById(), update(), delete(), etc. are extracted into a reusable class (either a base class or by aggregation).
You can also create additional repositories for non-domain information, e.g. statistical data. In these cases, make sure that you don't accidentally miss a domain concept, however.
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 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".
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.