Rule-based available values for a property within model - c#

I have a question regarding where to put available values of a specific property within a model class. Imagine you have a model class that has two properties Family and Series where the possible values of the Series property depends on the value of the Family property.
The business logic contains a set of rules that defines which Series values are available due to the value specified by the Family property. The model itself should always have a valid state, that means if the value of the Family property changes and the available values of the Series property also change, the value of the Series property itself must be changed to one of the available values to fit the valid state.
My intention is to display the available values within a ComboBox for both the Family property and the Series property. But at the moment I'm not sure whether to put the available values of the Series property
into the ViewModel,
into the Model,
or to introduce a separate layer between ViewModel and Model which covers data validation and the functionality of providing available values for specific properties within the model (that acts as plain data container).
I tend to use the second or third approach (I prefer the third approach) because of the directly dependent values within the model. This example in fact is very simple. The real problem covers about nearly 200 values where the available values of a single property can depend on up to 5 or 10 other properties.
In addition, the dependent values may not be located within a single model class and the concerning model classes do not know each other. So it is possible that the values that are required to get the available values for a property of a model class can be located within two or more other model classes.
What do you think is the best approach? Is there another (better) way to solve this I have not mention above?
Thanks,
Oliver

Since you already stated that the Model classes do not know each other, you certainly should not create dependencies just for the purpose of validation/aggregation/filtering (or whatever you might call it) on such a deep layer.
Your requirements generally fit the concerns of a ViewModel which cover value prepation among other things. On the other hand, you don't want to rely on a ViewModel doing that validation given that you model always has to be in a valid state. Just imagine you might add another client later that uses your Model data but can't use the ViewModels.
Therefore, an additional "layer" or service might be the best option in my opinion.

Related

How to keep correspondence between Domain and Presentation objects

I have a question about keeping track of objects in different layers of a software application. In my application, I have objects in the domain layer (e.g. LineShape) that are used to represent business entities, and I have corresponding objects in the presentation layer (e.g. System.Windows.Shapes.Line) that are used to display these entities on the screen.
My question is, how do I keep the correspondence between the domain objects and the presentation objects, so that I can identify which domain object is represented by a given presentation object?
For example, if the user clicks on a System.Windows.Shapes.Line in the user interface, how can I determine which LineShape in the domain layer this object represents?
I have thought of a few potential solutions, but none of them seem ideal, especially for larger and more complex object models.
One solution is to use a dictionary that maps presentation objects to domain objects. In this case, when the user clicks on a System.Windows.Shapes.Line, I could look up the corresponding LineShape in the dictionary.
Another solution is to use an ID for both the presentation and domain objects. This approach has the advantage of being simple, but it seems strange to me to use IDs for every object in a domain-driven design, as IDs are typically used only for entities.
Are there any best practices or established patterns for solving this problem?
Use an Id for objects both in Presentations and Domain. This sounds a
bit strange to me, because as far as I am aware, we are not supposed
to use Id for every object in DDD, just for entities.
Perhaps you would be looking at an address rather than an ID. Even values must somehow be addressed so they can be replaced. Such an address may be a class property's name, an array's index, etc.
If you see the whole drawing as a collection of shape values then you could always use the shape's index as the address allowing to replace that specific shape value in the collection.
However, note that the address is only valid as long as you are working against the expected drawing's version.
Furthermore, you could also use the combination of all shape's properties to identify a given shape to modify. If you have two identical shapes (same shape, position, layer, etc.), does it matter which one you re-shape? The final drawing would look exactly the same.
In the end if it makes your life easier to model shapes as entities and given them an ID then perhaps that's the right model too even though you may not care about the specific shape's entire lifecycle.
Finally, note that if shapes are values then you can't possibly keep a reference to them in view models since values are immutable. Also, if shapes are entities, but the drawing is the Aggregate Root then shape entities shouldn't be accessible outside the root. Therefore it most likely only makes sense to reference a domain's Shape in the view model if it's an AR (unless you violate the visibility rule, but still enforce invariants through root-handled events). Also note that address/ID references may be the only option if your domain model lives on another tier.
You've asked a somewhat broad question, so I will give what I think is a correct but general answer.
In WPF, one way or another, the on-screen controls will have a DataContext. The DataContext generally speaking should be the object you want to get a hold of.
This should be the case more or less regardless of what method you use to populate all the screen controls.
It may suit your program to create special viewmodel classes which bridge between your "native" data objects, in which case those viewmodel classes will be set as the DataContext objects. If you don't need the viewmodel then the native data objects will play that role.
If you are using events, then in the code-behind for the event you can directly access the DataContext property, cast it to the expected type, and off you go.
If you are using commands then generally they are part of the viewmodel object in the first place, so they can just act directly on the object which owns them.

MVVM Calculated Fields in Model or ViewModel?

I am trying to determine the correct pattern for handling Calculated fields or methods in MVVM. I have a number of calculated fields that will be required for both the presentation layer and some back end processing. Let say it is "CalculateTotal" which is based on summing a number of different values from the Data object and its sub objects.
I would like this calculation in one location. The first thought is that it belongs in the model (i.e., not the viewModel) since the model object will be passed to other back end processing systems. What is then the best way to make this available to the ViewModel?
Option 1, is that I statically load the viewModel when I create it based off the Model (e.g., vwModel.Total = model.CalculateTotal())
This suffers if I am needing to update the ViewModel dynamcally, for example I modify the underlying data and try to get the new total.
Option 2: More service oriented and each calculation calls a service to return the values. The issue I see with this is more performance based. Once I load my object once, I have all the data needed to perform the calculation. It seems each call would require the data object to be reloaded
Option 3: Have the ViewModel contain the data model and create methods to call the data model methods
Thoughts? Suggestions?
I would do all calculations in the model. The view model should subscribe to events (e.g. via INotifyPropertyChanged) on the model, so when the back-end values change, the view model will be notified.
The view model can, of course, interrogate the model for calculations and doesn't have to get all information through events. The above is only for when the data changes come directly from the model or the underlying data layer.
I would go with something like option 2. Moving the calculation logic out of the model and view model will simplify things and make that logic more reusable by other classes. From your question it seems like you already have an idea of how to implement that. Keeping the model "dumb" and having services/utility/helper classes that know how to process the model will help you in the long run if the model is being passed around a lot. Just something to think about but keeping the responsibility of a class very limited makes for easier code maintenance down the road. You might end up with more classes but I personally find it easier to focus and work on two or three small classes than one very large class. I don't know what type of application you have or how heavy the calculations are but unless you are having measurable performance issues I wouldn't worry about trying to pre-optimize things.
I would like this calculation in one location.
If there is a dedicated Service Layer, then almost all calculations should be done in Service Layer.
Option 1
Instead of using CalculateTotal method on Model, it's better make a read only property Total and calculate it in a service layer method every time Model is requested. This is the easiest and the best option to use if there are no performance issues, since it drastically simplifies ViewModel.
Option 2
Calling a dedicated CalculateTotal service method from ViewModel is the only option available if calculation process is resource intensive and calculated total is not used every time Model is requested.

In DDD how to pass Value Objects via DTO?

In my domain each Domain Entity may have many Value Objects. I have created value objects to represent money, weight, count, length, volume, percentage, etc.
Each of these value objects contains both a numeric value and a unit of measure. E.g. money contains the monetary value and the currency ($, euro,...) , weight contains the numeric value and the unit of weight (kilo, pound, ...)
In the user interface these are displayed side-by-side as well: field name, its value followed by its accompanying unit, typically in a properties panel. The domain entities have equivalent DTOs that are exposed to the UI.
I have been searching for the best way to transfer the value objects inside the DTOs to the UI.
Do I simply expose the specific value object as a part of the DTO?
Do I expose a generic "value object"-equivalent that provides name/value/unit in a DTO?
Do I split it into separate name/value/unit members inside the DTO, just to reassemble them in the UI?
Do I transfer them as a KeyValuePair or Tuple inside the DTO?
Something else?
I have searched intensively but no other question seems to quite address this issue. Greatly appreciate any suggestions!
EDIT:
In the UI both values and units could get changed and sent back to the domain to update.
I would be inclined to agree with debuggr's comment above if these are one-way transfers; Value Objects aren't really Domain objects - they have no behaviour that can change their state and therefore in many ways they are only specialised "bit-buckets" in that you can serialise them without losing context.
However; if you have followed DDD practices (or if your back-end is using multi-threading, etc) then your Value Objects are immutable i.e they perhaps look something like this:
public class Money
{
readonly decimal _amount;
readonly string _currency;
public decimal Amount {get{return _amount;}}
public decimal Currency {get{return _currency;}}
public Money(decimal amount, string currency)
{
//validity checks here and then
_amount=amount;
_currency=currency;
}
}
Now if you need to send these back from the client, you can't easily re-use them directly in DTO objects unless whatever DTO mapping system you have (custom WebAPI Model binder, Automapper, etc) can easily let you bind the DTO to a Value Object using constructors...which may or may not be a problem for you, it could get messy :)
I would tend to stay away from "generic" DTO objects for things like this though, bear in mind that on the UI you still want some semblance of the "Domain" for the client-side code to work with (regardless of if that's Javascript on a Web Page or C# on a Form/Console, or whatever). Plus, it tends to be only a matter of time before you find an exceptional Value Object that has Name/Value/Unit/Plus One Weird Property specific to that Value concept
The only "fool-proof"*** way of handling this is one DTO per Value Object; although this is extra work you can't really go wrong - if you have lots and lots of these Value Objects, you can always write a simple DTO generation tool or use a T4 template to generate them for you, based on the public properties of your Value Objects.
***not a guarantee
DDD is all about behavior and explicitly expressing intent, next to clearly identifying the bounded contexts (transactional and organizational boundaries) for the problem you are trying to solve. This is far more important than the type of "structural" questions for which you are requesting answers.
I.e. starting from the "Domain Entities" that may have "Value Objects", where "Domain Entities" are mapped as a "DTO" to show/be edited in a UI is a statement about how you have structured things, that says nothing about what a user is trying to achieve in this UI, nor what the organization is required to do in response to this (i.e. the real business rules, such as awarding discounts, changing a shipping address, recommending other products a user might be interested in, changing a billing currency, etc).
It appears from your description, that you have a domain model that is mirroring what needs to be viewed/edited on a UI. That is kinda "putting the horse behind the carriage". Now you have a lot of "tiers" that provide no added value, and add a lot of complexity.
Let me try to explain what I mean, using the (simplified) example that was mentioned on having an "Order" with "Money". Using the approach that was mentioned, trying to show this on screen would likely involve the following steps:
Read the "Order Entity" for a given OrderId and its related "Money" values (likely in Order Lines for specific Product Types with a given Quantity and Unit Price). This would require a SQL statement with several joins (if using a SQL DB).
Map each of these somehow to a mirroring "domain objects" structure.
Map these again to mirroring a "DTO" object hierarchy.
Map these "DTO" objects to "View" or "ViewModel" objects in the UI.
That is a lot of work that in this example has not yielded any benefit of having a model which is supposed to capture and execute business logic.
Now as the next step, the user is editing fields in a UI. And you somehow have to marshal this back to your domain entity using the reverse route and try to infer the user's intent from the fields that were changed and subsequently apply business rules to that.
So say for instance that the user changes the currency on the "MoneyDTO" of a line item. What could be the user's intent? Make this the new Billing Currency and change it for all other line items as well? And how does this relate to the business rules? Do you need to look up the exchange rate and change the "Moneys" for all line items? Is there different business logic for more volatile currencies? Do you need to switch to new rules regarding VAT?
Those are the types of questions that seem to be more relevant for your domain, and would likely lead to a structure of domain entities and services that is different from the model which is viewed/modified on a UI.
Why not simply store the viewmodel in your database (e.g. as Json so it can be retrieved with a single query and rendered directly), so that you do not need additional translation layers to show it to a user. Also, why not structure your UI to reveal intent, and map this to commands to be sent to your domain service. E.g. a "change shipping address" command is likely relevant in the "shipping" bounded context of your organisation, "change billing currency" is relevant in the "billing" bounded context.
Also, if you complement this with domain events that are generated from your domain, denoting something that "has happened" you get additional benefits. For example the "order line added" event could be picked up by the "Additional Products A User Might Be Interested In" service, that in response updates the "Suggested Products" viewmodel in the UI for the user.
I would recommend you to have a look at concepts from CQRS as one possible means for dealing with these types of problems. As a very basic introduction with some more detailed references you could check out Martin Fowler's take on this: http://martinfowler.com/bliki/CQRS.html

C# MVVM TreeView TwoWay-Binding of hierarchical data

I googled for an answer to this for more than two weeks now. This usually means either I am blind or the idea is absurd. Anyways:
In a middle-sized, quite flexible project I'm storing configuration data in a hierarchical structure in the like of this one:
Configuration (collection)
Audio (class)
BaseDir (struct)
PlayMode (enum)
Input (class)
CalibrateOnConnect (bool)
KnownDevices (collection)
... (class)
...
UseDevice (integer)
Playlist (collection)
FirstAudio (class)
Path (string)
Repeat (integer)
...
I already managed to display these in a TreeView in a MVVM pattern. Since I can't exactly tell which options will be added in future, I used a generic approach, creating ViewModels for class, ienumerable, my custom structs and the basic value types (string, bool, enum, ...).
In my XAML these have their corresponding (Hierarchical)DataTemplates, e.g. with a CheckBox for booleans or a textblock for general value types.
Each ViewModel instance has a field to store the data of the underlying Model.
I manage to edit these values in the View and via TwoWay-Binding also in the ViewModel.
But what makes my head hurt is how to update this data in the Model.
Since I create the hierarchical ViewModel structure through reflection, the parents do not have get/set properties corresponding to the field names / indexers / ... of the equivalent configuration class / collection. Though each ViewModel instance knows the field/property name of the parent's model's data structure it was created from and knows its parent ViewModel instance, too (but not its parent Model instance).
Every attempt to solve this problem via Commands or by calling some parent's update function made a knot into my brain.
Isn't there a simple way to achieve this via regular binding techniques?
Would it be better if I created ViewModels for each configuration (sub)class I'm using?
Hint: Each ViewModel instance knows its field / property name in the parent's model's data structure.
Reading through the comments I'd argue that a view model should be tightly coupled to the model that it is trying to represent. Having a dynamic view model is also very hard to test.
However, if you really wanted to try to get around this, you could consider using a DynamicObject which allows you to get/set properties on the instance in a completely generic fashion. With DynamicObjects you are then given hooks that are called when a property is either set or got, this would enable you (for example) to raise NotifyPropertyChange events for a given dynamic property.

Adding arbitrary properties to a strongly typed list

I'm looking for a good way to add arbitrary properties to the objects in a strongly typed list, based on the principle that I shouldn't pass a DataTable from my business layer to my presentation layer.
For example, I might have a Category class with the properties CategoryId and Title. On one page I would like to fetch a list of all categories (ie. List<Category>) together with the most expensive product in each category.
A while ago, I would have just returned a DataTable with some additional columns in it with the product data in, but I'm trying not to do that -- it would be trivial to set up it's not good practice.
One option is to add a MostExpensiveProduct property to my Category class, but I might want to display the most recently added product in another case, or the cheapest product, so I'd end up adding a lot of properties to cover all the options. This just doesn't feel right to me.
Am I missing a trick here? What is the best way of doing this? Or should I just be returning a DataTable to which I can add as many columns as I need and not worry about it?
The issue seems to be you have a lot of different views you'd like to offer the user. The options I see are:
You could construct separate classes for each view that inherit from the Category class. Code gen would be a good solution here.
You could store an Attributes property, which has an IDictionary interface, and refer to items by key. I'm becoming a fan of this approach.
You could generate a data table only for binding purposes, for these views... or develop a data table like component where you can refer to fields by Key...
For fields that you compute (say you store sales tax and net price, and compute gross cost), you could store as a method of the Category object, or as an extension method.
I'm sure there are other options that I haven't thought about...
HTH.
You should create a specialized class (a view model) for each view you have containing only the properties you are interested in using in the view. This may seem like unnecessary duplication for the simplest cases, but pays off in terms of consistency and separation of layers. You can construct the view models manually, or if that gets tedious, use an object-object mapping framework like AutoMapper.
There are several things to consider here IMHO. First, it seems that the only reference from Category to Product should be Category.Products, meaning you should never have something like Category.MostExpensiveProdcut etc. As far as your business layer, I would do something like this:
From your code behind in the presentation layer:
call CategoryManager.GetCategories();
call List<Product>ProductManager.GetMostExpensiveProducts(List<Category>);
Now that you have a list of Categories, and a list of Products (assuming your Product has a reference back to its Category) you have all the necessary information to work with. Using this setup your entities (Category, Product) are not polluted.
Another thing to consider is introducing a services layer. If you find that you don't want (for whatever reason) to make two calls to the business managers, rather you want to make a single call and get all your information in one shot I would consider introducing a services layer sometimes aka "application facade". This facade would be responsible for making the individual calls to the business managers and combining results into one response before shipping it back to the UI layer. Someone mentioned that that custom object would be a "ViewModel", which is correct but often used in reference to MVC. Another name for it would be a DTO (Data Transfer Object), which designed for use with service layers/application facade.

Categories

Resources