Is it possible to mix aspects that call different parts of a class (ie Methods and Properties)?

Pretty much as per the subject line. Consider the following scenario where one has aspects to log methods, Properties and eventually (subject to future metalama developments) Events. I would like to create fabric extension methods that would add all two / three at the same time.
16 Replies
domsinclair
domsinclairOP2y ago
Very much pseudo code here but something along the following lines is what I am aspiring to;
public static void LogEverything(this IProjectAmender amender)
{
amender.Outbound
.SelectMany(compilation => compilation.AllTypes)
.Where(type => !type.IsStatic)
.SelectMany(type => type.Methods || type.Properties)
.Where(method => method.Name != "ToString")
.AddAspectIfEligible<LogMethodAttribute>() || <LogPropertyAttribute>();

}
public static void LogEverything(this IProjectAmender amender)
{
amender.Outbound
.SelectMany(compilation => compilation.AllTypes)
.Where(type => !type.IsStatic)
.SelectMany(type => type.Methods || type.Properties)
.Where(method => method.Name != "ToString")
.AddAspectIfEligible<LogMethodAttribute>() || <LogPropertyAttribute>();

}
Gael Fraiteur
Gael Fraiteur2y ago
You mean one aspect class that targets both methods and properties? essentially you would do class TheAspect : Attribute, IAspect<IMethod>, IAspect<IFieldOrProperty>
domsinclair
domsinclairOP2y ago
No, one fabric that would allow you to add both aspects.
Petr Onderka
Petr Onderka2y ago
Would type.MethodsAndAccessors() work for you, or do you actually need special processing for properties?
Gael Fraiteur
Gael Fraiteur2y ago
Yes fabrics can add many aspects, no problem with that You can do many queries, reuse query parts, etc.
domsinclair
domsinclairOP2y ago
I take it though, or at least my possibly flawed experimentation to date suggests that you can't do that in one single method?
Petr Onderka
Petr Onderka2y ago
Can you share an example that doesn't work?
domsinclair
domsinclairOP2y ago
I'm trying to do something along the lines of the pseudo code above but a specific example of something that doesn't work is; .SelectMany(type => type.Methods && type.Properties) Now I freely admit my Linq knowledge is not as good as it ought to be, especially for this sort of situation.
Petr Onderka
Petr Onderka2y ago
You could do .SelectMany(type => type.Methods.Concat<IMember>(type.Properties)), but I don't think that's going to lead where you want.
domsinclair
domsinclairOP2y ago
This may be one of those cases where less turns out to be more in the overall scheme of things.
Petr Onderka
Petr Onderka2y ago
I would probably do something like this:
var types = amender.Outbound
.SelectMany(compilation => compilation.AllTypes)
.Where(type => !type.IsStatic);
types.SelectMany(type => type.Methods)
.Where(method => method.Name != "ToString")
.AddAspectIfEligible<LogMethodAttribute>();
types.SelectMany(type => type.Properties)
.AddAspectIfEligible<LogPropertyAttribute>();
var types = amender.Outbound
.SelectMany(compilation => compilation.AllTypes)
.Where(type => !type.IsStatic);
types.SelectMany(type => type.Methods)
.Where(method => method.Name != "ToString")
.AddAspectIfEligible<LogMethodAttribute>();
types.SelectMany(type => type.Properties)
.AddAspectIfEligible<LogPropertyAttribute>();
(Again, assuming using MethodsAndAccessors() is not enough.)
domsinclair
domsinclairOP2y ago
@petronderka I hadn't graped the significance of .MethodsAndAccessors sorry, closer to the goal now just need to tidy up the last bit which it doesn't like; amender.Outbound .SelectMany(compilation => compilation.AllTypes) .Where(type => !type.IsStatic) .SelectMany(type => type.MethodsAndAccessors()) .Where(method => method.Name != "ToString") .AddAspectIfEligible<LogMethodAttribute>() .AddAspectIfEligble<LogPropertyAttribute>();
Petr Onderka
Petr Onderka2y ago
An accessor is an IMethod, not an IProperty, so .AddAspectIfEligible<LogMethodAttribute>() should be enough.
domsinclair
domsinclairOP2y ago
But the Log Method Attribute doesn't log Properties? Which means that MethodsandAccessors won't work.
Petr Onderka
Petr Onderka2y ago
If you use it with MethodsAndAccessors, then it will log methods and property accessors.
domsinclair
domsinclairOP2y ago
Ok thanks, I'll do some experimentation with this a little later on
Want results from more Discord servers?
Add your server