I'm new in DDD/ Clean Architecture
I'm trying to implement this architecture in a new from scratch application and I feel confused in some points.
I'm trying to make the best choice to not regret it as application will start growing.
Probably my question is a bit stupid, but again i'm new in DDD and trying to make the best choices.
I'm trying to stick to this example https://github.com/ardalis/CleanArchitecture from Ardalis
Here is my model/problem simplified
-ApplicationAggregateRoot
---Application
---Instance
Application has a list of Instance.
Now I have to do an HTTPRequest "/operationA" on the Instance, this can be done by my blazor UI or by my API via controllers.
The result of this HTTP Request "/operationA" will have to be saved in my repository, and do other stuff, so from what I understood here I need an event when I have the HTPP Response something like "OperationAFinishedEvent"
What I don't really know how to figure it out is how should I make this call in my controller/blazor for example.
Should I do (pseudo code):
A)
_repository.GetApplicationById(1).Instances.First(i => i == id).OperationA()
and have some event raised in OperationA() Method of Instance
(something like "OperationASentEvent") which will be wired to a handler that will call _httpClient.OperationA(instance.Url)
Or should I pass by a domain service class for doing the call instead of an event like:
B)
class Controller
{
OperationA(Instance instance)
{
_instanceService.OperationA(instance)
}
}
class InstanceService
{
void OperationA(Instance instance)
{
_httpClient.OperationA(instance.Url);
new OperationAFinishedEvent(instance);
}
}
C) Or call directly
_httpClient.OperationA(instance.Url);
new OperationAFinishedEvent(instance);
from both controller and blazor
Or maybe something else ?
Thank's
It sounds like you have a Blazor client side app as well as a server-side app that you access via an API. So let's address both sides of the app.
In Blazor, you're typically going to minimize application logic and mostly just make calls to the API. So the code required to kick off an operation for an application instance in Blazor should look like this:
var result = await _httpClient.PostAsync(endpointUrl, data);
If that's a long-running process, you might bet back a result that provides you with another endpoint you can query for status. Otherwise the result should just let you know if the process completed successfully or not.
In your API, you will have various endpoints. Normally these endpoints correspond to resources and operations you can take to alter the state of these resources. Your API resources usually correspond to your domain model, but not always 100%. You should generally avoid using HTTP APIs for Remote Procedure Call (RPC) operations, since they're not really designed for that purpose. Instead, think in terms of requests and responses, typically. Imagine you're trying to get your city government to do something, and the way you do that is by filling out a form to hand to a clerk. Then when the action has been completed, they hand you back some more paperwork. The clerk is your API. The papers are your request and response objects. The actual action - the "instance operation" is happening back inside the office where you don't see it as a client, and none of your interactions are with it directly.
So you might have a resource like this:
/Applications/123/Instances/234/PendingOperations
You can list pending operations. You can POST a new operation request. Etc. There might also be a resource for .../CompletedOperations or you might get back an id for your pending operation that you can later use to view its status. The idea is to have an endpoint that represents a noun (a resource) and not a verb (do something).
Hope that helps!
Your domain layer (aggregate root is in there) should only be concerned about their internal state.
The applications layer (where you also use the repository) can call an interface to an other service, using the data from the aggregate root.
The interface is then implemented in a seperate layer.
Related
Background
I'm building a two-tiered C# .net application:
Tier 1: Winforms client application using the MVP (Model-View-Presenter) design pattern.
Tier 2: WebAPI RESTful service sitting on top of Entity Framework and SQL Server.
If you would like more detail on the application I'm building, I gave a probably too thorough explanation here.
Current Development
Currently, I'm working on the Winforms client. Particularly, I'm trying to hash out a adequate implementation of the command pattern within this client. I was fortunate enough to stumble across this excellent blog post that outlines a solid command architecture. To complement that post, the author followed up by explaining how he separates queries from commands. After reading those blogs, it becomes very clear that my tier 2 (web api service) would greatly benefit from implementing both of these. The generic implementation allows for fantastic flexibility, testability, and extensibility.
Question
What is less clear to me is how I go about implementing these patterns on the winforms client side of things (tier 1). Do queries and commands continue to be considered separate here? Consider a basic action, such as a login attempt. Is that a query or a command? Ultimately, you need data back (user information on the server) from the web service, so that would make me think it is a query. What about another case, such as a request to create a new user. I understand that you would create a command object that stores the user information and send that off to the service. Commands are supposed to be fire and forget, but wouldn't you want some sort of confirmation from the service that the command was successful? Furthermore, if a command handler returns void, how would you tell the presenter whether or not the user creation request was successful?
At the end of the day, for any given UI task (say the user creation request), does it end up that you end up having a winforms client based query/command, as well as a web api service version of the command/query which handles the request on that end?
Do queries and commands continue to be considered separate here?
Yes, typically you would fire a command and if you need to update the UI after this action has been performed you would perform a query to get the new information. An example will make this clear.
Let's say you would assign a specific guard to a certain area. The only information the command (which is only a DTO) needs is the Id of the guard and the Id of the area. The associated CommandHandler will perform all tasks to handle this, e.g. removing that guard from another area, booking him as unavailable etc.
Now your UI would want to show the change. The UI has probably some kind of list with all guards and their assigned area. This list will be populated by a single GetActiveGuardsAndAreaQuery which will return a List<GuardWithAreaInformationDto>. This DTO could contain all kinds of information about all guards. Returning this information from the command is not a clean separation of concerns, because the atomic command handling could be very well used from a similar but slightly different UI, which will require a slightly different update of the UI information.
such as a login attempt. Is that a query or a command?
IMO a login attempt is neither. It is a cross cutting concern, an implementation detail that the data is hidden behind a secure connection. The application however should not be concerned with this detail. Consider using the application with another customer where you could host the WebApi service in and Active Directory domain where you can use Windows Authentication. In that case the user only has to login to his machine and the security is handled by the client and server OS while communicating.
With the patterns you're referring to this can be nicely done using a AuthenticateToWebApiServiceCommandHandlerDecorator which makes sure their are login credentials to serve to the service by asking the user in a modal form, reading it from a config file, or whatever.
Checking if the credentials worked can be done by performing a kind of a standard Query your application always needs such as CheckIfUpdateIsAvailableQuery. If the query succeeds the login attempt succeeded otherwise it failed.
if a command handler returns void, how would you tell the presenter whether or not the user creation request was successful?
While it seems that void doesn't return anything this is not really true. Because if it doesn't fail with some exception (with a clear message what went wrong!) it must have succeeded.
In a follow up of the mentioned blog posts #dotnetjunkie describes a way to return information from commands but make notice of the added comment on the top of post.
To summarize, throw clear exceptions from failed commands. You can add an extra layer of abstraction client side to handle this nicely. Instead of injecting a commandhandler directly into the different presenters you can inject an IPromptableCommandHandler which has only one open generic implementation at compile time:
public interface IPromptableCommandHandler<TCommand>
{
void Handle(TCommand command, Action succesAction);
}
public class PromptableCommandHandler<TCommand> : IPromptableCommandHandler<TCommand>
{
private readonly ICommandHandler<TCommand> commandHandler;
public PromptableCommandHandler(ICommandHandler<TCommand> commandHandler)
{
this.commandHandler = commandHandler;
}
public void Handle(TCommand command, Action succesAction)
{
try
{
this.commandHandler.Handle(command);
succesAction.Invoke();
}
catch (Exception)
{
MessageBox.Show("An error occured, please try again.");
// possible other actions like logging
}
}
}
// use as:
public void SetGuardActive(Guid guardId)
{
this.promptableCommandHandler.Handle(new SetGuardActiveCommand(guardId),() =>
this.RefreshGuardsList());
}
At the end of the day, for any given UI task (say the user creation request), does it end up that you end up having a winforms client based query/command, as well as a web api service version of the command/query which handles the request on that end?
No!
Client side you should create a single open generic CommandHandlerProxy which solely task is to pass the command dto to the WebApi service.
For the service side architecture you should read another follow up: Writing Highly Maintainable WCF Services which describes an server side architecture to handle this very nicely. The linked project also contains an implementation for WebApi!
I'm designing a web service and a desktop client application that uses the web service. The interface has a requirement that you need to be able to perform multiple operations and commit them all at once. The operations are basic CRUD operations (create, read, update, delete).
Here's a rough, and Car-ified example of what the workflow would be:
The problem is that the service calls could be spread out over time. I originally had created a REST web service, but REST by definition shouldn't be transactional. The interface has to be able to commit all operations to the database in one go (upon a Save button click).
Edit: An important stipulation is that given the example above, a Car must exist in the database on the server in order to add seats to it. Within a transaction, that car should only be available to the person (session) who is working within that transaction. That limits the ability to send all the operations to the web service at one time at the end of the workflow.
The options I have considered so far are:
1) Implement distributed transactions using SOAP (WCF) and only commit when Save is clicked on the GUI. Is this possible/a good idea for longer transaction lifetimes?
2) Create a unit of work 'service' that takes operations and executes them all within one transaction on the server.
My question is, is 1) possible, or a good/bad idea? Is 2) a good idea, and are there any patterns/tools for implementing this across a web service (REST or SOAP)? Or is there a different way to handle this problem?
I would try this:
POST /unit-of-work
create with response 200
POST /car
create with response 202
POST /seat
create with response 202
etc.
PUT /unit-of-work
set "execute" bit, or somesuch
In this case, car, seat, etc have the unit-of-work specified when they're posted. When the unit-of-work is updated to be "done", all the items are executed.
Another approach would be:
POST /car
create with response 202
POST /seat
create with response 202
etc.
POST /unit-of-work response 200
In this case, car, seat, etc have a bit set saying they're not created yet. The unit-of-work should specify what resources belong to it, and then the back end can flip the bit on the other resources so they're created.
I have a long running operation you might read in couple of my another questions (for your reference here is first and second).
In the beginning of whole deal, project expose a form in which user should specify all necessary information about XML file and upload XML file itself. In that method all user input data caught and went to an WCF service that handles such king of files. Controller got only task id of such processing.
Then user got redirected to progress bar page and periodically retrieves status of task completeness, refreshes the progress bar.
So here is my issue comes. When processing of XML file if over, how can I get results back and show them to user?
I know that HTTP is stateless protocol but there is cookie mechanism that could help in this situation. Of course, I may just save processing results to some temporary place, like a static class in WCF server, but there is a high load on service, so it will eat all of supplied memory.
In other words, I would like to pass task to WCF service (using netNamedPipeBinding) and receive results back as fast as it really possible. I want to escape temporary saving result to some buffer and wait until client will gather it back.
As far as I go is using temporary buffer not on service side but at client's:
using (XmlProcessingServiceClient client = new XmlProcessingServiceClient())
{
client.AnalyzeXmlAsync(new Task { fileName = filePath, id = tid });
client.AnalyzeXmlCompleted += (sender, e) =>
{
System.Web.HttpContext.Current.Application.Lock();
// here is I just use single place for all clients. I know it is not right, it is just for illustrating purposes.
System.Web.HttpContext.Current.Application["Result"] = e;
System.Web.HttpContext.Current.Application.UnLock();
};
}
I suggest you to use a SignalR hub to address your problem. You have a way to call a method on the client directly to notify the operation completed. And this happen without having to deal with the actual infrastructure trouble there is in implementing such strategies. Plus SignalR plugs easily in an asp.net MVC application.
To be honest I didn't really get the part about the wcf server and stuff, but I think I can give you more of an abstract answer. To be sure:
You have a form with some fields + file upload
The user fills in the form and supplies an XML file
You send the XML file to an WFC services which procress it
Show in the mean time a progress bar which updates
After completion show the results
If this is not want you want or this is not what your question is about you can skip my answer, otherwise read on.
Before we begin: Step 3 is a bit ambiguous: It could mean that we send the data to the service and wait for it to return the result or that we send the data to the service and we donĀ“t wait for it to return the result.
Situation 1:
Create in a view the form with all the required fields
Create an action in your controller which handles the postback.
The action will send the data to the service and when the service returns the result, your action will render a view with the result.
On the submit button you add an javascript on click event. This will trigger an ajax call to some server side code which will return the progress.
The javascript shows some sort of status bar with the correct progress and repeats itself every x seconds
When the controller finishes it will show the result
Situation 2:
-
-
After sending the data to the service the controller shows a view with the progress bar.
We add an javascript event on document ready which checks the status of the xml file and updates a progressbar. (same as the onclick event in step 4 in situation 1)
When the progressbar reaches 100% it will redirect to a different page which shows the results
Does this answer your question?
Best regards,
BHD
netNamedPipeBinding will not work for cross-machine communication if this is what you have in mind.
If you want to host our service on IIS then you will need one of the bindings that use HTTP as their transport protocol. Have a look at the duplex services that allow both endpoints to send messages. This way the server can send messages to the client anytime it wishes to. You could created a callback interface for progress reporting. If the task is going to take a considerable amount of time to complete, then the overhead of the progress reporting through HTTP might be ok.
Also have a look at Building and Accessing Duplex Services if you want to use a duplex communication over HTTP with Silverlight (PollingDuplexHttpBinding).
Finally you could look for a Comet implementation for ASP.NET. In CodeProject you will at least a couple (CometAsync and PokeIn).
I'm not sure if this is the best solution but I was able to do something similar. This was the general setup:
Controller A initialized a new class with the parameters for the action to be performed and passed the user's session object
The new class called a method in a background thread which updated the user's session as it progressed
Controller B had json methods that when called by client side javascript, checked the user's session data and returned the latest progress.
This thread states that using the session object in such a way is bad but I'm sure you can do something similar with a thread safe storage method like sql or a temp file.
My applciation works as follows
[user]----username/password/domain----->[WCF service]
then i access the domain server to see to which actual DB the user is associated,
after getting that, i validate the user in his actual DB(DB is per domain)
the problem is that i need a place to store the domain name for the following requests against the db.
for example,if the users calls a WCF service operation:
Test()
first the validation procedure is called, (WCF UserNamePasswordValidator) which validates the user password(which is sent as part of the header for REST or as part of the SOAP), and the next function to be called is the Test, but by then i cant tell the domain of the user(to actually serve the request agains that domain..)
I dont want to change the signature of each domain to
Test(string domain)
I cant simply access the headers since i expose the same methods both as REST and as SOAP and the authentication is different for each of them..(one is with headers as with Amazon S3 and the later is using the SOAP standard)
so basically i'm looking for a global, per call storage.(i want to avoid the Per-Call initiation method)
thanks.
EDIT:
Maybe i should use the ThreadStaticAttribute? will that work?
This will not work. You can't store anything in UserNamePasswordValidator. It even doesn't have access to OperationContext because it runs on different thread.
The way to do this is create custom message inspector and extract the information from custom message header to custom operation context extension as Frank mentioned.
WCF knows a Current OperationContext. You can write your own extensions for it. Unrelated to this issue, I used the same mechanics in this NHibernate Session management here, which may work in its concept for you as well. It accesses the InstanceContext, but the concepts are similar.
I have a WCF service, marked with the OperationContract attribute.
I have a potentially long running task I want to perform when this operation is carried out, but I don't want the caller (in this case Silverlight) to have to wait for that to complete.
What is my best option for this?
I was thinking of either
something like the OnActionExecuted method of ActionFilterAttibute in System.Web.Mvc, but couldn't see an equivilent.
something listening to an event. (The process I want to call is a static, so I'm not too sure about this approach)
something else:
In the scenario I'm working in, I lock the app so the user cannot make any changes during the save until I get the response (a status code) back.
Keep in mind, Silverlight won't actually have to 'wait' for the call to finish. When you create a service reference within Silverlight you will automatically get async calls.
Assuming you really don't need to wait for the call to finish (ie: your service method uses a 'void' return type) you can mark the service method as one-way via:
[OperationContract(IsOneWay = true)]
void MyServiceMethod(some args);
In general, I suggest having another process service handle long-running actions. Create a simple Windows Service, and have it pull requests from an MSMQ queue via WCF. Have the main service post requests to the background service, then return to its caller. If anyone cares about the results, then the results may be placed in an output queue, and the Silverlight application could get them by querying the output queue.
You might also look into Windows Workflow Foundation, which is made to fit very well with WCF. In fact, you can have just this kind of service, where all the logic of the service is in the workflow. If the workflow takes too long, it can be persisted to disk until it's ready to go again.
my suggestion is to go for nettcp binding for your distributed computing
try it and you will get a solution for your problem
for nettcpbinding usage please follow below link
http://msdn.microsoft.com/en-us/library/ff183865.aspx