Search code examples
c#design-patternsattributesenforcement

Is there a way I can enforce a method to follow certain method signature?


let's say I have

public delegate DataSet AutoCompleteDelegate(
      string filter, long rowOffset);

can I make the following class to enforce that method signature? (just a conjured up idea):

public class MiddleTier
{
    [Follow(AutoCompleteDelegate)]
    public DataSet Customer_AutoComplete(string filter, long rowOffset)
    {
        var c = Connect();
        // some code here
    }

    [Follow(AutoCompleteDelegate)]
    public DataSet Item_AutoComplete(string filter, long rowOffset)
    {
        var c = Connect();
        // some code here
    }



    // this should give compilation error, doesn't follow method signature
    [Follow(AutoCompleteDelegate)]
    public DataSet BranchOffice_AutoComplete(string filter, string rowOffset)
    {
        var c = Connect();
        // some code here
    }         

}

[EDIT]

Purpose: I already put attributes in my middletier's methods. I have methods like this:

public abstract class MiddleTier : MarshalByRefObject
{
    // Operation.Save is just an enum

    [Task("Invoice", Operation.Save)]
    public Invoice_Save(object pk, DataSet delta);

    [Task("Receipt", Operation.Save)]
    public Receipt_Save(object pk, DataSet delta);


    // compiler cannot flag if someone deviates from team's standard
    [Task("Receipt", Operation.Save)]
    public Receipt_Save(object pk, object[] delta); 
}

then on runtime, i'll iterate all the middletier's methods and put them to collection(attributes helps a lot here), then map them on winform's delegate functions(facilitated by interface, plugins-based system) as loaded

I'm thinking if I can make the attributes more self-describing, so the compiler can catch inconsistencies.

namespace Craft
{        
    // public delegate DataSet SaveDelegate(object pk, DataSet delta); // defined in TaskAttribute

    public abstract class MiddleTier : MarshalByRefObject
    {

        [Task("Invoice", SaveDelegate)]        
        public abstract Invoice_Save(object pk, DataSet delta);

        [Task("Receipt", SaveDelegate)]
        // it's nice if the compiler can flag an error
        public abstract Receipt_Save(object pk, object[] delta);
    }
}

I'm thinking if putting the methods on each class, it would be an overkill to always instantiate a Remoting object. And putting them on separate class, it could be harder to facilitate code reuse, let's say Invoice_Save need some info on Receipt_Open. In fact I even have a report here(crystal), which fetched data from Remoting middletier DataSet, inside the invoked method, it gets some info on other methods and merge in its own DataSet, they are all happening on middletier, no several roundtrips, all are done on server-side(middle-tier)


Solution

  • You could implement both the FollowAttribute you use in your example and write a Static Analysis (say, FxCop) rule that could check if any method that is tagged with that attribute has the same signature as the mentioned delegate. So it should be possible.