Override property with BuildAspect

I create exceptions inheriting from Exception and putting the [BusinessException] attribute. I want to override the Message property using string.Format with the primary constructor parameters. For example, the next class:
[BusinessException]
public class UserAlreadyExistsException(int age, string email) : Exception;
[BusinessException]
public class UserAlreadyExistsException(int age, string email) : Exception;
I started with [Introduce], but later I noticed I need BuildAspect to access constructors. I've tried with this, but I don't know how to do complete the code. The goal is to have: string.Format("The user with age {0} and email {1} already exists", age, email); Code: https://try.metalama.net/#N4IgZiBcDaoHZRABQE4HsDmKCGBbAdAMYDOIANCIYgK7ECWcGABALICmALtgDZ7b4AxHLjYB3NCgDW+AILEADm0IdiAbgA6cWg2bsuvXPyF4xE6QGE0AEzYat9Rq048+g4aan4AotzoY6AEZ0vhwAnnaacCYK2IRsrKEAMoE4KOGamvLUAb6ETIS8xMRMAELacGxFXgAecfIcdGhwMhwcKIHUHPGQTAAqoYpyisqawJpME0zQAJJwbdbUcQAUAOoAFmxwNXTEKkwAvEwA8gBubCjtNgDKbdhdGKH4p+eXbACUALrjk1k5dHm7dqOdhFbAYNjfCZjOCTWFMcEcSFw6Fw1FME7YFBMLq4eS8LoHJjqEC9DZMWjnJiiOgcNZMMHxYAABgAvvS4FYmGxDMEmMAAIxsngoNjYKyhLnVHYqYl2NFwkUcagoGGAnSCCSGDhLHF4u5sMhEkDEw3E4lvOVollI60wyZI365JhoM4XOg2dFod2lajBKxDJTa6YB5RlP3nAA80wAciYrP1FAA+JgBX3cGwoN5IlFogLYYhsfBh9Mh7Wp8OZiJ21EYrEiUHg1BoRQoMKE8vp874XqYhFI+X4JsthqVftowR0FC7JbVA7J6r4WMiA6HYkg4gM82WmuYpjyTEmLpT9tpjPd3ucMeo-CWOCAxYcCTEK9widT7VZ6vypiDg8iI9qBkX6wmAEiioQdJLLWe5-pwlIMDB7gAZ+8o5t+Kanl2MhWCc-yFrM8xWIsbBDucYRLCh6EYRWsg4XhTyuq8Sz1hujboMOoSGpRqK2rCtosuQICSIgHAgCyHwskAA
5 Replies
Petr Onderka
Petr Onderka17mo ago
You can access constructors from a template, like this:
[Introduce(WhenExists = OverrideStrategy.Override)]
public string Message
{
get
{
var parameters = meta.Target.Type
.Constructors
.First()
.Parameters;

var template = "The user with age {0} and email {1} already exists";
return string.Format(template, parameters[0].Value, parameters[1].Value);
}
}
[Introduce(WhenExists = OverrideStrategy.Override)]
public string Message
{
get
{
var parameters = meta.Target.Type
.Constructors
.First()
.Parameters;

var template = "The user with age {0} and email {1} already exists";
return string.Format(template, parameters[0].Value, parameters[1].Value);
}
}
But keep in mind that Metalama does not support preview features of C#, so this is not guaranteed to work. (And to make sure you're aware of this, we require you to specify <MetalamaAllowPreviewLanguageFeatures>true</MetalamaAllowPreviewLanguageFeatures> in your project file.) In particular, there are some things that don't work well: 1. It doesn't work if the exception class has no body (;), it requires at least an empty body ({}). 2. There is no way to tell if a constructor is primary.
Andreu
AndreuOP17mo ago
Thanks! But can I do anything to use an empty body? For example, generate properties and use string.Format with them, use a preview version of Metalama, anything?
Petr Onderka
Petr Onderka17mo ago
Do you mean no body? (Empty body should work.) There is currently nothing you can do, Metalama simply does not expect that a class could have no body and so it won't work if you want to introduce something there.
Andreu
AndreuOP17mo ago
Yes, I mean that. Then, if I can't apply any hack meanwhile it gets proper support, please, can you tell me what's the approximate time Metalama will need to support the new C# version? It's because my library needs yes or yes C# 12 and .NET 8
Petr Onderka
Petr Onderka17mo ago
Proper support will come very soon after Microsoft releases C# 12, which will be in November.
Want results from more Discord servers?
Add your server