DTO is simplified. Dynamic tuples. How? Let's look at a possible solution

I was thinking about the possible use of a dynamic keyword.

Being a major advocate (say, a paladin) of strongly typed programming languages, I needed to open my mind and try to think of an alternative way of doing things.

Something that I find difficult to find is how layers and layers are conveyed with data transfer objects (DTOs).

How many dozens of DTOs do you need to cover data transfer through your application or service? I am sure that we can count many of them in any well-executed project.

But what about translating an object into a DTO? You end up creating dozens of DTOs that transfer information from multiple domains to objects that have arisen in some transactions, threads, or processes.

After all, what are the most important things to keep in mind when developing software? - Money and / or time first. Sizing a project using the right solution with available resources. - Create a supported, scalable, complete, well-designed application. All with our limited resources.

Speaking of the second point, what can be used and scaled? An incredibly robust design that has thousands of classes, interfaces, ... to maintain and improve? Yes. Think of a well-executed DDD, MVC, solution. It is easy to follow, improve, correct ... But not in terms of time. You can do it right, but it will take a lot of time.

Perhaps there is a solution for this with the flagship dynamic language Runtime and its associated “dynamic” keyword in C # 4.0 on top of the .NET Framework 4.0.

Yes, dynamics seem evil if it is not for interacting or working with dynamic languages ​​... That's right! But, remembering what I said in the second sentence, I wanted to go ahead and think about this topic.

We have tuples. Good! We can enter multiple results as the return value in a method or property. We do not need a special DTO! Wrong, because we don’t have tuple names. How can we use code that produces results with properties such as "Item1, Item2, ItemN".

Tuples seem like a good solution, for example, to replace the use of the "out" keyword in methods such as bool TryParse (value, result) in Tuple TryParse (value T), but I don’t think it is a good replacement for DTO, because we we lose the meaning of the code ... The code is read no more.

Later I thought about how to create attribute tuples with attributes, but it has a drawback: you need reflection to get something like 'tuple.Return ("Name") "works fine. Discarded.

It was at that moment when I thought about dynamic and DLR? I figured out how to make dynamic tuples and work with them.

Maybe something similar, but I want to discuss with you if you find it fine or not:

    public static class DynamicTupleExtensions { public static dynamic Return(this IEnumerable source, Func returnPredicate) { return source.Select(result => returnPredicate(result)).Single(); } public static IEnumerable> ToTuple(this IEnumerable source) { return source.Select(dynamicTuple => Tuple.Create((T1)dynamicTuple.GetType().GetProperties()[0].GetValue(dynamicTuple, null))); } public static IEnumerable Cast(this IEnumerable source) { return source.Select(dynamicTuple => JsonConvert.DeserializeObject(JsonConvert.SerializeObject(dynamicTuple))); } public static T Cast(this object source) where T : class { return JsonConvert.DeserializeObject(JsonConvert.SerializeObject(source)); } } public class StronglyTypedResult { public int Value { get; set; } } public class Program { private static void Main(string[] args) { int result = AddOne(10).Return(value => value.Value); Tuple resultAsTuple = AddOne(10).ToTuple().Single(); StronglyTypedResult typedResult = AddOne(10).Cast().Single(); Console.WriteLine(result); Console.Read(); } private static IEnumerable AddOne(int value) { return new List { new { Value = value + 1 } }; } } 

As you look at the code, you’ll see that I am “tricking” anonymous types and the dynamic keyword into creating an enumerable number of dynamic tuples.

Later, you can get the dynamic value of a tuple using three approaches: - Complete search for tuples based on a dynamic framework. - Convert to a typed tuple. - Transmission as DTO (this conversion).

The first one is the most controversial: it uses the full dynamic as-is tuple. You lose compilation type checking, but you get more flexibility. I would use it in a project with high discipline and strong guidance on naming and convention (this is paradise, I know that).

Secondly, it is a combination of checking compile time and runtime: a tuple is processed dynamically, but you get a strongly typed tuple. This loses the named root solution in the first approach. This approach will be used in the body of the method, where it is possible there is no access to the classes representing the DTO, or you do not have them, or there is no implementation for them (just like the first option).

Finally, the third is the safest solution: you use dynamic tuples at some layer or level, and wherever you have classes representing DTO, you add dynamic tuples to DTO, and this works like the actual and most C # DTO. This is not a good option because I use the JSON serializer to compile the C # compiler and convert the convertible on the fly from an anonymous type to a strongly typed DTO.

At the end of the day, what is the question? The question is, what is your opinion on this decision?

  • Is it supported?

  • What will be the impact of this approach on performance?

  • Do you think discipline is the only requirement to follow this approach or is it just a big failure?

  • Do you think that this decision is a big failure, and this is a big collapse in terms of creating well-designed solutions?

This is just a software philosophy. And I am sure that this approximation will have defenders and haters.

Keep in mind that this is not a “question that considers this to be the best solution”, but I am just throwing here the conclusion that I want to share with everyone.

Thanks for reading, and I hope you all have good moments (even if you hate my conclusions about that!).

+4
source share
2 answers

At the end (in one or two years), your early discussion became true and more popular ( here) with the help of the "Dynamic Linking Model with ASP.NET WEB API". The basic idea is to avoid the number of DTOs using dynamics, and thus increase flexibility.

 public Class Controller : APIController() { public dynamic Post(dynamic contract) { return contract; } } 
+3
source

It seems that you are looking for a combination of AutoMapper Dynamic Mapping and ExpandoObject . With some creative thought, you could probably achieve your goal this way.

+2
source

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


All Articles