How to request a permission from a different view? - mvvm

I have a Project which contains three views: A MainView, which contains the two other views.
The two sub-views contain Lists of Objects (Let's call them View A and B), which are largely independent. But sometimes there is a connection between the objects, which are contained in the Lists.
Since the dawn of time, only Objects from List A "knew" about objects of Type B, Type B has no Idea that A could exist.
This was intended behaviour and would be difficult to change. But know I have a Problem: Objects from List B can be deleted, but that is not a good idea when it is referenced by an Object of Type A.
Would I would like to do is to somehow "ask" View A, if some of its objects are having a connection to the Object to be deleted. If so, I would inform the user.
But how can I model that? The Views A and B don't know each other. Going through the MainView would be "wrong". I would use an event, but If I understand Caliburn correctly, I can only send an event, but cannot recieve feedback.
Any Ideas?

EventAggregator looks like a solution.
Your user select an object and clicks delete.
your click handler in View B sends a message1 with id (or whatever you use to identify) of object to delete.
View A receives the message1 and sends a message2 with the result of the check (delete/ don't delete)
View B receives the message2 and deletes the object or warns the User.
message1 and message2 are completely independent, different types.

Related

Displaying multiple different-overlapping lists in different views with Flutter

Hey allI am trying to achieve the following behavior:
There are two Objects.
Y(bool saved, int id) and X(Y y, bool liked, int id)
Three views ViewA, ViewB, and ViewC can be accessed from a BottomNavBar. So all of them will be loaded during app usage. Views A and B will display a list of X and View C will display a list of Y. Even though A and B will show different lists, some items might be the same. Also, some of the nested Y's in the X's might be displayed on ViewC as well.
Items being the same requires me to synchronize all of the lists in some way. I have been thinking about this but so far could not come up with an efficient solution.
My current implementation is as follows:
xRepo has a Map<int, BehaviorSubject> allX that will keep a map of streamcontrollers that my xBloc will subscribe to. the integer here is the id of the X or Y objects. The same goes for yRepo and a streamcontroller to be subscribed by yBlocs.
I also have a single ListBloc which takes care of fetching the lists of X and Y, and asking the repo to update each fetched item by the newly fetched one. Upon fetching a list of Xs, I update both the allX and allY streamcontrollers (because the fetch of X might include up to date information about the Y objects) I use a ListView that builds a list of xCards and yCards in the corresponding views. I use xBloc and yBloc provided to each xCard and yCard to subscribe to the streamcontroller that is mapped with the id of the item allX and allY streamcontrollers. This way, an update in the saved value of Ys and liked value of Xs will be reflected to all of the UIs at the same time.
This implementation causes my app to be clanky because the Bloc provided to each card subscribes to the corresponding streamcontroller in allX or allY. And I think scrolling these cards up and down hurts the rendering in some way.
I need a better, more efficient implementation. Sorry the way I described the problem was too complicated. The problem is a rather complicated one for me.

How to reference the same object that comes from diferents streams?

I have an application with an api works like a web (when you ask for 'favorites' it sends a json with some elements that fit in the category, when you ask for all the elements it sends another list, which contains the favorites as well, but when the json is transformed it will be a reference of a different object).
I am trying to find the best way, not to make a call each time, storing the view in a tab and working with 'streams' instead of 'builders', but how to update the object if in a category view we assign a value to it, and when we go back to the full list tab (without reloading), show the change in the object that represents the same one that we have in favorites?
Actually I am storing the first reference of the object in a block, in an array of objects, if we first call 'favorites' the next time the same object arrives from another source, it references the first occurrence of the same object, it works, but the object list can be very large and I'm afraid maybe not the best implementation.
In a prefect world I would like not to have to store the objects and just work with the tabs loaded in streams, but I don't know how to propagate the change if the same item is on different tabs.
Any idea for a good implementation?

Is there a hard definition of how CQRS should be applied and CQRS questions

I have some trouble understanding what the CQRS pattern really is, on its core, meaning what are the red lines that, when crossed, we are not implementing the CQRS pattern.
I clearly understand the CQS pattern.
Suppose that we implement microservices with CQRS, without event sourcing.
1) First question is, does the CQRS pattern only apply to the client I/O? Meaning, hoping I get this right, that for example the client updates using controllers that write to database A, but read by querying controllers that write to database B, (B is eventually updated and may be aggregating information from multiple models using events sent by controller of A).
Or, this is not about the client, but anything, for example another microservice reading / writing? And if the latter, what is really the borderline that defines who is the reader / writer that causes the segregation?
Does this maybe have to do with the domains in DDD?
This is an important question in my mind, because without it, CQRS is just an interdependence, of model B being updated by model A, but not the reverse. And why wouldn't this be propagated from a model B to a model C for example?
I have also read articles stating that some people implement CQRS by having one Command Service and one Query Service, which even more complicates this.
2) Similar to the first question, why do some references speak of events as if they are the Commands of CQRS? This complicates CQRS in my mind, because, technically, with one request event we can ask a service "Hey please give me the information X" and the service can respond with an event that contains the payload, effectively doing a query. Is this a hard rule, or just an example to state that, we can update using events and we can query using REST?
3) What if, in most cases I write to model A, and I read from model B, but in some cases I read directly from model A?
Am I breaking CQRS?
What if my querying needs are very simple, should I duplicate model A in this situation?
4) What if, as stated in question 1), I read from model A to emit events, to produce model B, but then I like to read some information from model B because it's valuable because it is aggregated, in order to produce model C?
Am I breaking CQRS?
What is the controller that populates model B doing in that case, e.g. if it also emits events to populate model C? Is it simply a Command anyway because it is not the part that queries, so we still apply CQRS?
Additionally, what if, we read from model A to emit events, to produce model B, but while we produce model B, we emit events, to send client notifications. Is that still CQRS?
5) When is CQRS broken?
If I have a controller that reads from model B, but also emits a message that updates model A, is that it?
Finally, if that controller, e.g. a REST controller, reads from model B and simultaneously emits a message to update model A, but without containing any information from what was read from model B, (so the operation is two in one, but it does not use information from B to update A), is that still CQRS?
And, what if a REST controller, that updates model A, also returns some information to the client, that has been read from A, does that break CQRS? What if this is just an id? And what if the id is not read from A, but it is just a reference number that is randomly generated? Is there a problem in that case because the REST controller updates, but also returns something to the user?
I will really appreciate your patience for replying as it can be seen that I'm still quite confused and that I'm in the process of learning!
Is there a hard definition of how CQRS should be applied and CQRS questions
Yes, start with Greg Young.
CQRS is simply the creation of two objects where there was previously only one. The separation occurs based upon whether the methods are a command or a query (the same definition that is used by Meyer in Command and Query Separation, a command is any method that mutates state and a query is any method that returns a value). -- Greg Young 2010
It's "just a pattern", born of the fact that data representations which are effective for queries are frequently not the patterns that are effective for tracking change. For example, using an RDBMS for storing business data may be our best choice for maintaining data integrity, but for certain kinds of queries we might want to use a replicate of that data in a graph database.
why do some references speak of events as if they are the Commands of CQRS
HandleEvent is a command. CommandReceived is an event. It's very easy for readers (and authors!) to confuse the contexts that are being described. They are all "just" messages, the semantics of one or the other really depend on the direction the message is traveling relative to the authority for the information in the message.
For example, if I fill out a form on an e-commerce site and submit; is the corresponding message an OrderSubmitted event? or is it a PlaceOrder command? Either spelling could be the correct one, depending on how you choose to model the ordering process.
What if, in most cases I write to model A, and I read from model B, but in some cases I read directly from model A? Am I breaking CQRS?
The CQRS police are not going to come after you if you read from write models. In many architectures, the business logic is executed in a stateless component, and will depend on reading the "current" state from some storage appliance -- in other words, to support write often requires a read.
Pessimizing a write model to support read use cases is the thing we are trying to avoid.
Also: horses for courses. It's entirely appropriate to restrict the use of CQRS to those cases where you can profit from it. When GET/PUT semantics of a single model work, you should prefer them to separate models for reads and writes.

CQRS events do not contain details needed for updating read model

There is one thing about CQRS I do not get: How to update the read model when the raised event does not contain the details needed for updating the read model.
Unfortunately, this is a quite common scenario.
Example: I add a user to a group, so I send a addUserToGroup(userId, groupId) command. This is received, handled by the command handler, the userAddedToGroup event is created, stored and published.
Now, an event handler receives this event and the both IDs. Now there shall be a view that lists all users with the names of the groups they're in. To update the read model for that view, we do need the user id (which we have) and the group name (which we don't have, we only have its id).
So the question is: How do I handle this scenario?
Currently, four options come to my mind, all with their specific disadvantages:
The read model asks the domain. => Forbidden, and not even possible, as the domain only has behavior, no (public) state.
The read model reads the group name from another table in the read model. => Works, but what if there is no matching table?
Add the neccessary data to the event. => Does not work, as this means that I had to update all previous events as well, and I cannot foresee which data I may need one day.
Do not handle the event via a "usual" event handler, but start an ETL process in the background that deals with the event store, creates the neccessary data and writes the read model. => Works, but to me this seems a little bit of way too much overhead for such a simple scenario.
So, the question is: How do I deal with this scenario correctly?
There are two common solutions.
1) "Event Enrichment" is where you indeed put information on the event that reflects the information you are mentioning, e.g. the group name. Doing this is somewhere between modeling your domain properly and cheating. If you know, for instance, that group names change, emitting the name at the moment of the change is not a bad idea. Imagine when you create a line item on a quote or invoice, you want to emit the price of the good sold on the invoice created event. This is because you must honor that price, even if it changes later.
2) Project several streams at once. Write a projector which watches information from the various streams and joins them together. You might watch user and group events as well as your user added to group event. Depending on the ordering of events in your system, you may know that a user is in a group before you know the name of the group, but you should know the general properties of your event store before you get going.
Events don't necessarily represent a one-to-one mapping of the commands that have initiated the process in the first place. For instance, if you have a command:
SubmitPurchaseOrder
Shopping Cart Id
Shipping Address
Billing Address
The resulting event might look like the following:
PurchaseOrderSubmitted
Items (Id, Name, Amount, Price)
Shipping Address
Shipping Provider
Our Shipping Cost
Shipping Cost billed to Customer
Billing Address
VAT %
VAT Amount
First Time Customer
...
Usually the information is available to the domain model (either by being provided by the command or as being known internal state of the concerned aggregate or by being calculated as part of processing.)
Additionally the event can be enriched by querying the read model or even a different BC (e.g. to retrieve the actual VAT % depending on state) during processing.
You're correctly assuming that events can (and probably will) change over time. This basically doesn't matter at all if you employ versioning: Add the new event (e.g. SubmitPurchaseOrderV2) and add an appropriate event handler to all the classes that are supposed to consume it. No need to change the old event, it can still be consumed since you don't modify the interface, you extend it. This basically comes down to a very good example of the Open/Closed Principle in practice.
Option 2 would be fine, your question about "what about the mismatching in the groups' name read-model table" wouldn´t apply. no data should be deleted, should invalidated when a previous event (say delete group) was emmited. In the end the row in the groups table is there effectively and you can read the group name without problem at all. The only apparent problem could be speed inconsistency, but thats another issue, events should be orderly processed no matter speed they are being processed.

iPhone -- Applying MVC when the view hierarchy has a parallel structure to the model hierarchy

I have a Triangle class. Each Triangle has three edges a, b, and c, and also three angles angleA, angleB, and angleC. In addition to the size (length or angle), each datum also stores whether it was entered by the user or was calculated based on geometric relationships to other data.
Corresponding to my Triangle class, I have a TriangleSidesAndAnglesView. This view has six subviews -- one for each of the angles, and one for each of the sides. The contents of the subviews depends on the information in the model class. The subviews are all of class TriangleDatumView.
Information can pass both ways. For example, if the user enters something in a text field corresponding to an edge or angle, the entered value needs to be passed up to the model.
I am trying to figure out how to keep everything organized. For example, should the TriangleDatumView objects contain references to the respective corresponding members in the model class? Does the TriangleSidesAndAnglesView need to keep a table of which TriangleDatumView corresponds to what model object? Should the TriangleDatumView for (say) edge b know that the name of the edge it is displaying is "b" so that it can write "b=" each time . . . or does it grab that info from the model?
Nothing here is fundamentally difficult. The challenge is organizing it all in a sensible way.
Thanks for any help.
A question I ask myself is "What do I want to be able to independently vary?" -- meaning, if I have a model, could I imagine a totally different implementation of the same interface or a totally different view for the same model. In the variations that I care about, what needs to be where.
So, if labels are always A, B, and C -- I see no reason to store labels in the model. If they can change, then yes, you should not hard-code them in the view.
Views in MVC often have references right to the model they are viewing. Sometimes the controller is an intermediary. Models should usually not contain references to views -- but instead use things like delegates to alert of changes to their state.
I'm in the "Do the simplest thing that works, and don't repeat yourself, refactor when necessary" camp. The issue with building in the complexity at the start is that it might be complex on the wrong axis -- let the features dictate how the interfaces grow.
A view controller could sit between model and view, managing an array of TriangleView instances. The controller adds, modifies and deletes views based on what is in the model, and does the same for model instances based upon changes to the parent view (typing in a text field, tapping and dragging, and other UI actions, etc.).