While Creating Custom Attributes a custom class is created which is extended from ValidationAttribute Class.
public class CustomAttribute: ValidationAttribute
{
public void Test()
{
Console.WriteLine("Hello World");
}
public override bool IsValid(object? value)
{
//Logic here
if (condition)
{
return true;
}
else
return false;
}
}
Let say this custom attribute is placed above a Property of a Model.
[Custom]
public string username { get; set; }
By placing Custom over the property I am instantiating the Custom Class. Now my query is
- How & When does the IsValid() Method is Called?
- Why not the Other Methods in CustomAttribute class not called?(In this case Test() Method)
- On What basis a particular Method run in the CustomAttribute Class?
CodePudding user response:
By placing
[Custom]
over the property I am instantiating theCustom
Class.
No, that is incorrect.
Attribute
instances are only created (and their constructors invoked) when you use the GetCustomAttributes()
methods. This is discussed here: When is a custom attribute's constructor run?
How & When does the
IsValid()
Method is Called?
Only when some validation service (which could be anything!) intentionally chooses to look for ValidationAttribute
subclasses using GetCustomAttributes()
and it specifically uses IsValid()
too.
Why not the Other Methods in
CustomAttribute
class not called? (In this caseTest()
Method)
Because none of the code you've posted shows any attempt to instantiate CustomAttribute
via reflection and call .Test()
on them.
On What basis a particular Method run in the
CustomAttribute
Class?
Only when the attribute is instantiated by GetCustomAttributes()
and the consumer (the calling program) is specifically written to use the methods in [CustomAttribute]
.
CodePudding user response:
Your basis of understanding isn't correct.
You are assuming what works here is an Attribute
while you need to focus on code behavior.
Attributes are "data" classes - they aren't acting on their own.
They are useful while performing Reflection
on classes and properties.
In the DLL or EXE you could see this data in work.
Attributes help to "Mark" certain things, I advise learning more about Reflection.
To your questions:
IsValid
is called by a framework or yourself, It needs to extract theseAttribute
types specifically and callIsValid
. A good hint is theoverride
keyword - means something else manages this behavior.- While this is possible - to extract by reflection all of public methods and invoke them, frameworks aren't designed to call custom public methods because it's unsafe, unexpected and generally not recommended.
- On framework basis - if a framework was designed to call these methods then they would call them, else it simply wouldn't care what methods you define.
For example let's assume this silly attribute:
public class MyAttrib : ValidationAttribute
{
public MyAttrib()
{
Console.WriteLine("Hello from attrib ctor");
}
public override bool IsValid(object? value)
{
if (value == null) return false;
if (value != null && value.GetType() != typeof(string))
{
return false;
}
string? s = value as string;
return s == "Hello World";
}
}
[MyAttrib]
public class A
{
}
The implementing framework needs to do something like so:
var assm = Assembly.GetExecutingAssembly();
foreach (var type in assm.GetTypes())
{
if (type.IsAssignableFrom(typeof(A)))
{
Console.WriteLine($"Found type {type}");
var attributeType = type.GetCustomAttribute<MyAttrib>();
var isValid = attributeType.IsValid("Hello World");
Console.WriteLine($"Is Valid? {isValid}");
}
}
I focused more on reflection because this is the key to understanding attributes.
A bit on frameworks like ASP.net:
These frameworks use extensively Reflection
to perform many tasks and "delegate" behavior to user code.
A fun experiment would be to put breakpoints on the methods you override
and see where in the code they are called.
Also check out different attributes and what they have, the basis for them is to mark certain data or behavior like the ValidationAttribute
to perform validation on the data.
Good luck!
CodePudding user response:
The system that is aware of ValidationAttributes does not know about your Test method. It does know about the IsValid method - that's why you needed to override it.