How to write a converter class? How to write matching rules efficiently?

I have a fairly large class A with a large number of participants, and I have a fairly large class B that can be created with object A. Object A can be created when object B. I need both, since A is a viewModel that has validation and B is a graphical description that can be easily constructed.

How to do this conversion?

here is an example to illustrate what i want to do:

class A { string s; string t; string u; string v; enum a; enum b; enum c; enum d; enum e; Dictionary<enum, string> dict; } class B { string someString; // is essentially Aa + Ab + Ac + As with some rules. int someValue; // is essentially dict.TryGetValue(enum.Entry); string anotherString; // ... and lots of others } 

Of course, it’s easy to do some mapping and create an object B, and it’s easy to write a simple map B => A by inverting the construction rule A => B

So the questions are:

  • Are there any known patterns to achieve this?
  • Is there a way to execute C # by default?

Writing something like this does not seem to fit, it ends with hundreds of lines of code.

I was thinking of some kind of converter classes for parts, e.g. SomeStringConverter, SomeValueConverter, ...

  • How can I abstract the necessary members of A along with the rules for display.
  • How can I write these rules to have the easiest way to execute A => B and B => A.

Edit: The sample here is referred to as "Best Practice" and not as "GoF Design Templates"

SomeString in class B is a kind of "selector", it selects a drawing of options, it is always 25 characters, and enumerations in class A select these characters, but not more often than 1 on 1.

Let's say for example: Aa = "Filled", Ab = "SingleCoordinate", Ac = "DrawHints" will lead to something like SomeString =

  "Y**D***RR****---***---***" 

i.e. the combination is important to get such a string, but from the combination you can get the enumerations that must be set in object A.

Edit2:

I am particularly interested in ways to use my matching rules for both ways, i.e. Aa = "Filled" in combination with Ab = "SingleCoordinate" associated with Ac = "DrawHints" will result in (partial string) "Y**D***RR" , and this partial string also means that Aa must be set to "Filled", etc.

+6
source share
5 answers

What I did to solve this problem:

  • Wrote BiMap (using older SOs on this issue).

  • Insert a mapping into it (all combinations of values ​​in Key, the received key in "Value", together with BitArray, which defines the row indices that are determined by this mapping.

  • Wrote some code to calculate the total total string from it, since the display would just give partial strings.

  • Individual mappings were trivial.

That way I could use comparisons in both directions. Given a string, I still have an expensive search (since I have to compute the saved string using BitArray as a mask)

This works very well at the moment, but I'm not finished yet.

Thank you all for your very good ideas and approaches! AutoMapper may be able to, but now I have little time to read and try new technology.

If anyone can provide some relevant examples of how to do this on Automapper, I will take this as an answer (since I already love AutoMapper).

Examples, such as let say: 3 listings with 5 values ​​for one fixed-length string, one fixed-length string up to 3 listings with 5 values ​​(back side above).

as an example:

 Aa && Bo && Cy ==> "**A**********************" Aa && Bp && Cy ==> "**B**********************" Ab && Bo && Cy ==> "*****X*******************" Ab && Bo && Cz ==> "*****W*******************" 

Can Automapper achieve such things?

0
source

It seems to me that A is more related to the data model, and B is more related to the view model. I don’t think that there is a generally accepted “model” for this kind of specimen - mainly because the reasons for this kind of pairing are very different, and the best model is highly dependent on the intended use.

However, since they are so closely related to each other, I would be inclined to make one class subordinate to another. In this case, since A is more straightforward, I would most likely use A as a data container for B. ie Have a private member A as a field in class B and all properties of class B of reference class A directly and update the properties in Instead to have their own private fields. Then you can have a public property of class B that provides a private member of class A, if necessary. I would suggest that this is read-only, but this is probably not very important (depending on your use of class B and any possible related relationships). To go the other way, I would then create a constructor of class B that takes class A as a parameter. Then, the passed value of A will be assigned to private class A in class B.

The result of everything that should maintain the unfamiliarity of class A of class B, which becomes useful if you have a real use case for the ViewModel situation. If you determine that class A is the correct ViewModel for your needs, then undo it so that class B is not aware of class A.

+4
source

Are there any well-known patterns to achieve this?

It depends on what you mean by the template. Decorator or Adapter templates come to mind, but none of them are designed for the wholesale display of types for different types.

Is there a way to execute C # by default?

No no. But libraries like Automapper make life easier.

+3
source

Factory + possibly Facade

You want to coordinate the construction of B from A or from B. This claims that you need complex logic for this.

To build B from A, either implement it as a static method in B (Factory), or create a new class C that inherits from B and takes argument A as its constructor (Facade).

Factory: http://en.wikipedia.org/wiki/Factory_method_pattern (Not an exact match for your situation)

Facade: http://en.wikipedia.org/wiki/Design_Pattern_-_Facade (not an exact match)

0
source

A few thoughts:

A) Change B to an interface that implements A. This will allow you to “map” properties B directly to objects A without the need to recreate them. In cases where B has a property that A should not have (or a property that combines several of A), you can set the access modifier to private * - this means that the property will be displayed only through the interface (so that there is no confusion or mess implementation A).

B) Use the pseudo adapter / wrapper pattern. B specified by a constructor parameter of type A can refer to properties of A, etc. Where B is different, it can implement its own logic.

The juxtaposition between two complex objects requires some complex thinking. There will always be special cases, side effects and choices that require thought and a balance of pros and cons. (For example, the conversion between a string and an int introduces all kinds of questions - what to do with the thousands separator, how to handle different cultures, etc.). From reading your specific circumstances, I don’t see a simple or quick way to handle the display - you will use a method based on all the factors involved, perhaps too much to publish here.

EDIT: * I have to point out that this is what I have done in several VB projects. I assume this is legal in C #, but I have not tried.

0
source

Source: https://habr.com/ru/post/919067/


All Articles