3

I have got several classes looking like the one below, and I need to do some checks in the get method and custom set methods. Adding the code in each get and set method makes everything look really messed up.

Is there a way I can override the get and set methods for all properties in an entire class?

public class Test
{
    private DataRow _dr;
    public Test()
    {
        _dr = GetData();
    }

    public string Name
    {
        get { return _dr[MethodBase.GetCurrentMethod().Name.Substring(4)].ToString(); }
        set
        {
            VerifyAccess(MethodBase.GetCurrentMethod().Name.Substring(4), this.GetType().Name);
            _dr[MethodBase.GetCurrentMethod().Name.Substring(4)] = value;
        }
    }

    public string Description
    {
        get { return _dr[MethodBase.GetCurrentMethod().Name.Substring(4)].ToString(); }
        set
        {
            VerifyAccess(MethodBase.GetCurrentMethod().Name.Substring(4), this.GetType().Name);
            _dr[MethodBase.GetCurrentMethod().Name.Substring(4)] = value;
        }
    }

    public string DescriptionUrl
    {
        get { return _dr[MethodBase.GetCurrentMethod().Name.Substring(4)].ToString(); }
        set
        {
            VerifyAccess(MethodBase.GetCurrentMethod().Name.Substring(4), this.GetType().Name);
            _dr[MethodBase.GetCurrentMethod().Name.Substring(4)]= value;
        }
    }


    private void VerifyAccess(string propertyname, string classname)
    {
        //some code to verify that the current user has access to update the property
        //Throw exception
    }

    private DataRow GetData()
    {
        //Some code to pull the data from the database
    }
}
tkalve
  • 3,066
  • 4
  • 24
  • 29

6 Answers6

1

Not directly, there isn't a way to do it with just a compiler. You'd have to generate your entire binary file, then post-process it with some external tool.

This post describes a somewhat similar issue; I hope it helps.

Community
  • 1
  • 1
user541686
  • 205,094
  • 128
  • 528
  • 886
1

I think what you need is a Proxy on your class, read about Proxy Pattern and Dynamic Proxies

Jahan Zinedine
  • 14,616
  • 5
  • 46
  • 70
1

There's a variety of ways to do it. One would be to create a proxy class (mentioned before), but that would require a lot of refactoring on your behalf. Another way is with aspects. These do exactly what you're after (insert code based on a pre-requisite.. i.e. all get methods in a class that inherit from x). I ran into a similar problem (actually the exact same problem - checking for security on method calls), and couldn't find cheap/free aspect software that fulfilled my needs.

So, I decided to use Mono-Cecil to inject code before function calls.

If you're interested (it gets a bit messy dealing with IL codes) I can post an old copy of the source

Rob
  • 26,989
  • 16
  • 82
  • 98
0

I would love for someone to give a better answer for this.

I'm looking for an answer now… best idea I have had would be to define all the properties you want to have be validated as a generic class. For example:

public class Foo {
    public String Name { 
        get{ return _Name.value; }
        set{ _Name.value = value; }
    }
    private Proxy<String> _Name;

    static void main(String[] args) {
        Foo f = new Foo();

        //will go through the logic in Proxy.
        f.Name = "test"; 
        String s = f.Name;
    }
}
public class Proxy<T> {
    public T value { 
        get { 
            //logic here
            return _this; 
        } set {
            //logic here
            _this = value;
        } 
    }
    private T _this;
}
Joseph Nields
  • 5,527
  • 2
  • 32
  • 48
0

You should extract common code to separate get/set methods, after that you'll be able to add common logic to your properties. By the way, I would do such extraction anyway to avoid copy/paste in the code.

Smth like this:

public string Name
{
    get { return GetProperty(MethodBase.GetCurrentMethod()); }
    set
    {
        SetProperty(MethodBase.GetCurrentMethod(), value);
    }
}

private string GetProperty(MethodBase method)
{
    return _dr[method.Name.Substring(4)].ToString();
}

private void SetProperty(MethodBase method, string value)
{
    string methodName = method.Name.Substring(4);
    VerifyAccess(methodName , this.GetType().Name);
    _dr[methodName] = value;
}
Andrew Bezzub
  • 15,744
  • 7
  • 51
  • 73
0

This can be done with indirect value access, e.g. obj.PropA.Value = obj.PropB.Value + 1 -- you can even keep strong typing information. It can be implemented with either attributes or direct-instantiation.

// attribute -- bind later in central spot with annotation application
[MyCustomProp(4)] CustProp<int> Age;

// direct -- explicit binding, could also post-process dynamically
CustProp<int> Age = new CustProp<int>(4, this);

Alternatively, perhaps using a template system such as TT4 may be a viable approach.

However, don't forget "KISS" :-)