jwaliszko / ExpressiveAnnotations

Annotation-based conditional validation library.
MIT License
351 stars 123 forks source link

Validating using static method from another class #165

Closed paulodiogo closed 5 years ago

paulodiogo commented 7 years ago

Firstly thanks for your library it has already saved me pain and is pretty nice.

I have this situation:


public class X
{
    public static bool IsValid(string y)
    {
        //return if y is valid
    }
 }

public class XViewModel
{
    [AssertThat("X.IsValid(Y)", ErrorMessage = "Y is invalid.")]
    public string Y { get; set; }

}

This situation can be possible some day?

jwaliszko commented 7 years ago

Hi, technically nothing prevents us from extending the functionality in the appointed direction, but is it really necessary? I do realize it's not the same, but the simple workaround is as follows:

public class X
{
    public static bool IsValid(string y)
    {
        //return if y is valid
    }
 }

public class XViewModel
{
    [AssertThat("IsValid(Y)", ErrorMessage = "Y is invalid.")]
    public string Y { get; set; }

    public bool IsValid(string y) // model-level method
    {
        return X.IsValid(y);
    }
}

Alternatively, if you need utility-like function, accessed globally - across all expressions within every model, register it in toolchain instead of defining it for specific model only, i.e.

protected void Application_Start()
{
     Toolchain.Instance.AddFunction<string, bool>("IsValid", y => X.IsValid(y)); // utility method

Extending the already existing functionality to handle arbitrary static methods directly within expressions, will introduce further complexity. What's more, addMethod() is not going to help us at the client-side. While there is no problem with server-side, at client there is no X context available, so the expression evaluation will fail - the solution could be to provide some additional extension - let's say - addSubModel(), which could be next used to enhance the base model with subsequent objects, e.g.

ea.addSubModel({
    X: {
        IsValid: function(val) {
            // return ...
        }
    }
});

Nevertheless, it is something which is to be considered.

paulodiogo commented 7 years ago

Hi, thanks for the response, I did exactly that workaround. =D