1

I am new to AOP and post sharp (2.1.0.0). I have been experimenting with property/method interception and am able to write inteceptor aspects for classes which I have written.

My goal is to not have lists with any logic in them before compile time.

An example of what I want to achieve is:

public class Foo
{
    //Implementation should throw an exception if more than 1 string added.
    public List<string> MyList { get; set; }
}

One thing I am not sure about are lists. I want to be able to run some validation when either Add() or Remove() is called on a list. I think I can do this if I wrap the list in my own custom list class and decorate the class with the aspect attribute.

I know I can accomplish this using my own custom list and do something clever in my own implementations of Add/Remove - but this is what I would prefer to avoid if possible.

Is there any other (or a better) way of intercepting these methods - specifically using post sharp?

Jay
  • 9,561
  • 7
  • 51
  • 72

2 Answers2

3

There is no way to modify the List<T> class in this way because the Add method is not virtual. If the MyList property returned an IList<string> instead, then the object returned by it could perform this type of validation.

The .NET framework provides the Collection<T> class to help you extend certain list functionality. The easiest way to implement the feature you describe is deriving a class from it and perform the validation in InsertItem.

The Collection<T> class implements IList<string>, so you'll still need to change the property type of Foo.MyList.

Edit for AOP: If you wanted to use AOP for this feature, instead of returning a list from MyList that the user manipulates, the Foo class would provide Add and Remove methods that performed the necessary validation before making changes to a backing list. In this case I would return ReadOnlyCollection<T> from the MyList property to make it clear that the list is only manipulated via methods provided in Foo.

Sam Harwell
  • 97,721
  • 20
  • 209
  • 280
  • I can subclass List and declare an implementation of add() using the 'new' keyword. This does my validation - and if the validation passes it calls base.add(). It's a little bit nasty but it works. That wasn't really what I was asking tho. – Jay Mar 26 '13 at 15:15
  • 1
    @Jay No, it does not work. It's important to understand this or you'll have a very hard time tracking down inevitable problems if you try it. http://stackoverflow.com/questions/1626049/overriding-listts-add – Sam Harwell Mar 26 '13 at 15:19
  • Good point - thanks for the link, I think I'll just go with wrapping the List and applying my aspects to the wrapped version. – Jay Mar 26 '13 at 15:25
1

There isn't a collection changed event for a generic List in .NET. I know you don't want to hear this, but you either need to wrap List or you need to create a class that implements IList.

Caleb Keith
  • 816
  • 4
  • 10
  • Thats cool - I only wanted to avoid it if at all possible. I know you can hook into events using postsharp (but haven't explored that yet) - so if I had a list that did raise events, do you know if it would be preferable to write aspects to get those events, or just write aspects to intercept the add/remove? – Jay Mar 26 '13 at 15:07
  • I would write the class, implement IList and have a backing list to store the items in (to make it simple). You can then implement INotifyCollectionChanged and raise the event when an add/remove/clear is performed. See: http://msdn.microsoft.com/en-us/library/ms668629.aspx – Caleb Keith Mar 26 '13 at 15:27