Should An Application Service Be Injected Into A Domain Service - entity-framework

I am working on a WinForms application using Entity Framework 6 with the following layers:
Presentation
Application
Domain
Infrastructure
When a user clicks the save button from the UI, it calls an application service in the Application layer and passes in the request. The application service then calls a domain service with the request. The domain service calls on an several entities within a domain model to perform validations on data used in the request.
One or more validations in the domain model require information from a repository to determine if data in the request received from the Presentation Layer conforms to certain business rules.
I am considering two options to address this.
Have the Application Service retrieve the information needed from
the repositories for validation and pass those values into the
Domain Service which will call on the domain model and entities to
validate the incoming request for rules and values. Then let the
Application Service save the request when the Domain Service has
finished its validations, which will result in returning control
back to the Application Service which was synchronously waiting for
completion of validations. If I do this, then the domain layer will
have no direct or indirect (injected) reference to the repositories.
Unit testing of the Domain Service will be easier if I do this
because nothing is injected into it to perform validations.
Everything it needs is already passed in. The drawback is that some
business knowledge is put into the Application Service because now
it needs to know which repository information to retrieve for
validations of a request.
When calling the domain service for validation of the request,
inject an instance of the Application Service into it. The Domain
Service can then get information from the repository using the
injected Application Service, whose service contract is defined in
the Domain Layer. Once all the information is available it is passed
as needed to various entities to validate rules and values. Once
validation is completed, the Domain Service saves the request using
the injected Application Service. When the Domain Service is done
and exits, it returns the status of the save operation to the
Application Service which has been waiting for validation to
complete. The outer waiting application service can then return the
results of the save to the UI. One concern I have here is that when
unit testing the Domain Service I will have to mock the injected
Application Service.
Which option or other course of action would work out better? Thanks in advance.

"Should An Application Service Be Injected Into A Domain Service"
No, never!
Resolving the data from the application service and passing it to the domain service is usually fine, but if you think that domain logic is leaking then
you can apply the Interface Segregation Principle (ISP) and define an interface in the domain based on what contract is required to query for the "wanted data". Implement that interface on your repository or any other object that can fulfill the task and inject it into your domain service.
E.g. (pseudo-code)
//domain
public interface WantedDataProvider {
public WantedData findWantedData(...) {}
}
public class SomeDomainService {
WantedDataProvider wantedDataProvider;
}
//infrastructure
public class SomeRepository implements WantedDataProvider {
public WantedData findWantedData(...) {
//implementation
}
}
EDIT:
I have a request aggregate root with an employee name. One rule is the
employee must be full time and not a contractor
If the information to perform the validation already exists on an aggregate, you may also use this AR as a factory for other ARs. Assuming an employee holds it's contract type...
Employee employee = employeeRepository.findById(employeeId);
Request request = employee.submitRequest(requestDetails); //throws if not full time
requestRepository.add(request);
Note that the invariant can only be made eventually consistent here, unless you change your aggregate boundaries, but it's the same with the other solutions.

When a significant process or transformation in the domain is not a natural responsibility of an Entity or Value Object, add an operation to the model as a standalone interface declared as a Service. Define the interface in terms of the language of the model and make sure the operation name is part of the Ubiquitous Language. Make the Service stateless - Evans, the Blue Book
Don't lean to heavily toward modelling a domain concept as a Service. Do so only if the circumstances fit. If we aren't careful,, we might start to treat Services as our modelling "silver bullet". Using Services overzealously will usually result in the negative consequences of creating an Anemnic Domain Model, where all the domain logic resides in Services. - Vernon, the Red Book
What I am trying to tell by extensive citing, is that you seems to see Domain Services as something you MUST have where you absolutely don't have to do it. Your application services can happily use repositories to fetch the aggregate and then call the aggregate root method to perform necessary operations. Your aggregate root is responsible to protect its own invariants by executing necessary validations inside it and throw validation exception if anything should go wrong.
In case you absolutely must use a domain service, if you are doing it right, meaning you implement onion architecture, where inner layers do not know about outer layers, your domain service won't be able to know about the application service. However, you can, if you absolutely have to, send a delegate into the domain service to do something that the application service desires. However, this scenario is too complex to be true. Seeing that you only require the validation, please read the cited parts of the blue and red books and make the right decision. Again, there is no mandatory domain service in DDD, this is one of common misconceptions.

Related

Fetching potentially needed data from repository - DDD

We have (roughly) following architecture:
Application service does the infrastructure job - fetches data from repositories which are hidden behind interfaces.
Object graph is created and passed to appropriate domain service.
Domain service does it thing and raises appropriate events.
Events are handled in different application services which perform some persistent operations (altering repositories, sending e-mails etc).
However. Domain service (3) has become so complex that it requires data from different external APIs only if particular conditions are satisfied. For example - if Product X is of type Car, we need to know price of that car model from some external CatalogService (example invented) hidden behind ICatalogService. This operation is potentially expensive one (REST call).
How do we go about this?
A. Do we pre-fetch all data in Application Service listed as (1) even we might not need it? Do we inject interface ICatalogService into given Domain Service and fetch data only when needed? The latter solution might create performance issues if, some other client of Domain Service, calls this Domain Service repeatedly without knowing there is a REST call hidden inside it.
Or did we simply get the domain model wrong?
This question is related to Domain Driven Design.
How do we go about this?
There are two common patterns.
One is to pass the capability to make the query into the domain model, allowing the model to fetch the information itself when it is needed. What this will usually look like is defining an interface / a contract that will be consumed by the domain model, but implemented in the application/infrastructure layers.
The other is to extend the protocol between the domain model and the application, so that we can signal to the application layer what information is needed, and then the application code can decide how to provide it. You end up with something like a state machine for the processes, with the application code coordinating the exchange of information between the external api and the domain model.
If you use a bit of imagination, you've already got a state machine something like this; as your application code is already coordinating the movement of inputs to the repository and the domain model. The difference, of course, is that the existing "state machine" is simple and linear enough that it may not be obvious that there is a state machine present at all.
how exactly would you signal application layer?
Simple queries; which is to say, the application code pulls the information it needs out of the domain model and uses that information to compute the next action. When the action is completed, the application code pushes information to the domain model.
There isn't enough information to give you targeted good advice. I suspect you need to refactor your domains into further subdomains. It sounds like your domain service has way more than 1 responsibility. Keep the service simple.
In addition, If you have a long running task like a service call that takes a long time, then you need to architect it away. The most supple design will not keep the consumer waiting. It'll return immediately with some sort of result to the user even if it's simply a periodic status update.

Where to put my application logic when using Entity Framework and MVVM

In the last days I spent a lot of time creating the architecture for my program, but still have a problem with it. At the moment it looks like this:
DataLayer: Here my context class which derived from DbContext and the mapper classes which derived from EntityTypeConfiguration like JobMap for the Domain objects reside
DomainLayer: Here my domain/business objects like Job or Schedule reside.
Presentation Layer: Here I have the *ViewModel and *View classes (I use WPF for the views)
Now to my question: I want to build a scheduling application with some optimization abilities (it is a single user and single pc application so no further decoupling like web application is needed). But I have the problem that I don't know where this application fits into this architecture?
Considering the following use case: The user clicks a button "Start" on the View which calls the ViewModel which redirects to my scheduling/optimization application. This app then gets all the new jobs from the database and creates/updates the current schedule. The ViewModel should then update the old schedule with the new created one. Finally the View shows the generated schedule to the user.
In this case my ViewModel knows about my application (because it calls it) and about my domain/business objects (because my app will deliver e.g. a Schedule domain object, which the ViewModel encapsulates).
Is this a correct usage of the EF, MVVM and my application?
Regards
To start, you'll want to identify which pieces of your application go where, and that's fairly easy to do. Essentially, you have to ask yourself: Does this method or class help define my domain. If the answer is yes, you put it in the domain layer, and if not, you'll put it in presentation.
Here's how you'd look at it in your example:
Your Presentation layer (PL) receives a message via the start
button.
The PL calls the Domain and tells it to generate a schedule. This call is probably to a domain service.
Your domain service is then in charge of populating the Job domain objects, creating a new Schedule domain object (or modifying an existing one), and returning the Schedule domain object.
Your PL then simply displays the returned Schedule.
This might be different if you just wanted to obtain an existing Schedule object. Instead of calling a domain service, you would ask a domain repository to get the existing schedule. The repository would be the way of encapsulating or otherwise obscuring the data layer from your PL and from your Domain.
Now, what you DON'T want to do:
Do not get the list of jobs in your PL, and then use that list of jobs to create the schedule in the controller of your MVVM. This would be business logic that defines your domain.
If Schedules are commonly generated from Jobs, regardless of whether it's called from MVVM or a PHP site, then don't add complexity in your PL and Domain Layer by forcing the PL to first get the jobs and pass them back into the Domain for a Schedule to be generated. The fact that those two concepts are tied to each other means that the relationship helps define your domain, and thus belongs in your domain layer. An exception might be when both the jobs and the schedule to be modified both rely on context from the front end (user input), but even this isn't always an exception.
Do not pass in VMs to your domain. Let your controller filter out the data and determine what needs to be sent to which domain part.
It's really hard to give a precise detail of what you should place where because only you would have a clear view of what defines your domain, but here's essentially how I break it down:
Could I change/replace this without affecting how my business/domain works?
If the answer is yes, it does not belong in your domain. Example: You could replace your entire MVVM front-end to flat PHP or ASPX, and even though it'd be a lot of work and a huge pain, you could to do it without affecting how the rest of the business operates.

Fake services mock for local development

This has happend to me more than once, thought someone can give some insight.
I have worked on multiple projects where my project depends on external service. When I have to run the application locally, i would need that service to be up. But sometimes I would be coding to the next version of their service which may not be ready.
So the question is, is there already a way that can have a mock service up and running that i could configure with some request and responses?
For example, lets say that I have a local application that needs to make a rest call to some other service outside to obtain some data. E.g, say, for given a user, i need to find all pending shipments which would come from other service. But I dont have access to that service.
In order to run my application, i need a working external service but I dont have access to it in my environment. Is there a better way rather than having to create a fake service?
You should separate the communications concerns from your business logic (something I call "Edge Component" see here and here).
For one it will let you test the business logic by itself. It will also give you the opportunity to rethink the temporal coupling you currently have. e.g. you may want the layer that handle communications to pre-fetch, cache etc. data from other services so that you will also have more resilient services at run time

ContentResolver usage

I am new to andriod domain and is in learning phase. I got couple of queries:
Do we have single ContentResolver object per app?
Is it a singleton object?
Who manages this object lifecycle?
If it's singleton, how does it handles multiple request of querying a ContentProvider?
From Alex Lockwood's Blog -
http://www.androiddesignpatterns.com/2012/06/content-resolvers-and-content-providers.html
What is the Content Resolver?
The Content Resolver is the single, global instance in your
application that provides access to your (and other applications')
content providers. The Content Resolver behaves exactly as its name
implies: it accepts requests from clients, and resolves these requests
by directing them to the content provider with a distinct authority.
To do this, the Content Resolver stores a mapping from authorities to
Content Providers. This design is important, as it allows a simple and
secure means of accessing other applications' Content Providers.
The Content Resolver includes the CRUD (create, read, update, delete)
methods corresponding to the abstract methods (insert, delete, query,
update) in the Content Provider class. The Content Resolver does not
know the implementation of the Content Providers it is interacting
with (nor does it need to know); each method is passed an URI that
specifies the Content Provider to interact with.
What is a Content Provider?
Whereas the Content Resolver provides an abstraction from the
application's Content Providers, Content Providers provides an
abstraction from the underlying data source (i.e. a SQLite database).
They provide mechanisms for defining data security (i.e. by enforcing
read/write permissions) and offer a standard interface that connects
data in one process with code running in another process.
Content Providers provide an interface for publishing and consuming
data, based around a simple URI addressing model using the content://
schema. They enable you to decouble your application layers from the
underlying data layers, making your application data-source agnostic
by abstracting the underlying data source.
The Life of a Query
So what exactly is the step-by-step process behind a simple query? As
described above, when you query data from your database via the
content provider, you don't communicate with the provider directly.
Instead, you use the Content Resolver object to communicate with the
provider. The specific sequence of events that occurs when a query is
made is given below:
A call to getContentResolver().query(Uri, String, String, String, String) is made. The call invokes the Content Resolver's query
method, not the ContentProvider's.
When the query method is invoked, the Content Resolver parses the uri argument and extracts its authority.
The Content Resolver directs the request to the content provider registered with the (unique) authority. This is done by calling the
Content Provider's query method.
When the Content Provider's query method is invoked, the query is performed and a Cursor is returned (or an exception is thrown). The
resulting behavior depends entirely on the Content Provider's
implementation.

MVC Repository Pattern/Web Services SoC Question

I am new to ASP.NET MVC and I am trying to implement best practices for a small-to-mid size application that uses a web service as its data source. The web service exposes the following methods to support the application:
AuthenticateCustomer - returns the customer ID if valid email/password
GetCustomer - returns a serialized object containing customer information
Etc
My question is, all of these services return Success (bool) and Message (string) values depending on the result of the operation. The message contains descriptive information if an error occurred. I'm not sure if the invocation of the web services belongs in the Repository layer, but I think it is important to be able to pass the Success and Message values up through the Repository -> Service -> Controller layers. The only way I can think of doing this is by either littering the Repository methods with out arguments:
public int AuthenticateCustomer(string Email, string Password, out bool Success, out bool Message);
or create some sort of wrapper that contains the intended return value (integer) and the Success and Message values. However, each web service method returns different values so a one-size-fits-all wrapper would not work. Also, these values would need to be passed up through the Service layer, and it just seems like validation of some sort is happening at the Repository level.
Any thoughts on how to accomplish:
1. Separation of concerns (validation, data access via web service) while ...
2. Having the ability to maintain the feedback received from the web service and pass it through all the way to the View?
P.S. - Sorry for the terse question. It is a bit difficult to explain with any kind of brevity.
Do you need a repository? From what you described, I am viewing the Web Service as the repository. I would then use the Services (Business Layer) to call to the Web Service, and have the logic in there handle errors or success.
Have the Business Layer convert the Customer object from the Web Service into a Business object, and pass that on to the Controllers.
Repository (Web Services) -> Services (Business Layer) -> Presentation Layer (Controllers)
Martin's answer is good.
I could possibly see a case for a thin layer around the web services to facilitate testing.
If you do go that route and Success = false is not a common condition you could throw an Exception of your own type with Success and Message wrapped into it. I would only do this if it really was an exceptional condition. If you find your business layer catching the exception just to return an error code to the presentation layer, then it's the wrong approach.