1

I'm not sure this is what it's called, but here's what I'm trying to achieve:

I need to be able to specify an Attribute to properties, fields and classes, and every time an object with the [Attribute] specified will call a certain static function.

I already know how to set up the attribute, but I'm not sure how to go about intercepting the creation of every object and calling the function on it.

John Saunders
  • 160,644
  • 26
  • 247
  • 397
Yourstress
  • 19
  • 1
  • 2
    Perhaps use a custom attribute, and call the static method from that class's constructor? – BradleyDotNET Sep 08 '14 at 17:50
  • 3
    As far as I know, there is no way to "intercept" creating an object. You would need to create a [Factory](https://en.wikipedia.org/wiki/Factory_method_pattern) in order to assist with creating your objects, so that it could scan for and act on each attribute. – qJake Sep 08 '14 at 17:50
  • You could make a base class for such objects that checks for attributes in its constructor, as long as it's no problem that the base constructor is executed before the class constructor. – C.Evenhuis Sep 08 '14 at 17:53
  • I have never tried that but @BradleyDotNET seems to be on the right track. Considering that attribute is a class that would be instantiated in context of the class it is applied to, this might be of help. – Abhinav Sep 08 '14 at 17:54
  • why not call it from the constructor ? – eran otzap Sep 08 '14 at 17:54
  • If what you're after is object creation interception, you'll need either a factory or a proxy. You may achieve that by using a dependency injection container. If you're after interception of method calls via IL Weaving, look into one of the [Aspect Oriented Programming](http://stackoverflow.com/questions/633710/what-is-the-best-implementation-for-aop-in-net) frameworks available. – Yuval Itzchakov Sep 08 '14 at 17:55

1 Answers1

3

You cannot intercept an object being created without inserting some sort of code into the class itself, or creating a Factory around the class to manage instantiation.

Assuming you have a class like this:

public class MyData
{
    [Captialization]
    public string Name { get; set; }
}

With an attribute defined like this:

[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Class)]
public class CaptializationAttribute : Attribute { }

You can detect and manipulate the properties tagged with various attributes like this:

public static class DataUtilities
{
    public static void ApplyAttributes<T>(T obj)
    {
        // Capitalization attribute
        var props = typeof (T).GetProperties().Where(p => p.GetCustomAttributes(typeof (CaptializationAttribute), true).Any());
        foreach (var prop in props)
        {
            // This is just an example, if you use this code you 
            // should check if the property is a string first!

            prop.SetValue(obj, prop.GetValue(obj).ToString().ToUpper());

            // Or perform some other manipulation here.
        }
    }
}

Now, to invoke this code automatically, you need to decide when you want it to occur. If it's well after the instantiation, you'll likely have to call it yourself from somewhere. But if it's during instantiation, you can do one of two things:

Using a Factory:

public static class MyDataFactory
{
    public static MyData Create()
    {
        var myData = new MyData();
        DataUtilities.ApplyAttributes(myData);
        return myData;
    }
}

You'll likely want to use an internal constructor to prevent outside instantiation.

// No instantiation from outside the assembly
internal MyData() { }

Using the constructor:

Add the call to the manipulation utility into your constructor:

public MyData()
{
    DataUtilities.ApplyAttributes(this);
}

There are other methods of doing this, such as using a Proxy, Dependency Injection, or as @Yuval Itzchakov mentioned, an AOP framework, but the ones I described are probably the easiest to implement.

Community
  • 1
  • 1
qJake
  • 16,821
  • 17
  • 83
  • 135