6

I have a class where every method starts the same way:

internal class Foo {
  public void Bar() {
    if (!FooIsEnabled) return;
    //...
  }
  public void Baz() {
    if (!FooIsEnabled) return;
    //...
  }
  public void Bat() {
    if (!FooIsEnabled) return;
    //...
  }
}

Is there a nice way to require (and hopefully not write each time) the FooIsEnabled part for every public method in the class?

I check Is there an elegant way to make every method in a class start with a certain block of code?, but that question is for Java, and its answer are using Java Library.

Community
  • 1
  • 1
0x6773
  • 1,116
  • 1
  • 14
  • 33
  • You could use something like DynamicProxy to weave this in at runtime. – Sneal Jul 01 '15 at 05:39
  • The answer is pretty much the same as the Java one - aspect oriented programming (e.g. PostSharp) or dynamic proxies. Or of course, code generation - just make a simple T4 template to generate the proxy at compile-time. – Luaan Jul 01 '15 at 05:40
  • There is even Fody as an alternative... modifying the assembly after compilation. Note that .NET doesn't have an in-language `java.lang.reflect.Proxy` – xanatos Jul 01 '15 at 05:42
  • Now more importantly why are you doing this and in which kind of solution? There could be builtin solutions in the platform you are using. – Janne Matikainen Jul 01 '15 at 05:48
  • 3
    You might want to consider a polymorphic solution. Extract a common interface and provide two implementations: one (`Foo`) that executes code in functions, and the other (`FooDisabled`) which simply provides dummy method implementations without a body. You can then instantiate the one you need in your specific case. – knittl Jul 01 '15 at 05:53
  • AOP but it may be pretty overkill if you start to use it just for this. A good old private member with a descriptive name...seems helpful and elegant enough (to me). Of course a base class and abstract implementation methods may also hide this in a class hierarchy but I've do it only if and when *required* – Adriano Repetti Jul 01 '15 at 05:57

3 Answers3

7

The principal your are looking for is Interception from the domain of Aspect Oriented Programming or AOP.

While C# does not directly support it, there are solid choices:

  1. Postsharp
  2. Unity Interception
  3. Spring.NET
  4. Castle Interceptors

If I get time tomorrow, I will cook up an example for you...

Aaron Anodide
  • 16,906
  • 15
  • 62
  • 121
4

I don't think you can easily get rid of the extra clutter in the Bar, Baz, Bat methods, but you can make it more manageable with creating a method to execute action you are passing in as such.

internal class Foo
{
    private bool FooIsEnabled;

    public void Bar()
    {
        Execute(() => Debug.WriteLine("Bar"));
    }

    public void Baz()
    {
        Execute(() => Debug.WriteLine("Baz"));
    }

    public void Bat()
    {
        Execute(() => Debug.WriteLine("Bat"));
    }

    public void Execute(Action operation)
    {
        if (operation == null)
            throw new ArgumentNullException("operation");

        if (!FooIsEnabled)
            return;

        operation.Invoke();
    }
}
Janne Matikainen
  • 5,061
  • 15
  • 21
2

Sure:

internal interface IFoo {
    void Bar();
    void Baz();
    void Bat();
}

internal class Foo {
    private IFoo FooImplementation = new DisabledFoo() // or new EnabledFoor()

    public bool FooIsEnabled
    {
        get
        {
            return FooImplementation is EnabledFoo;
        }
        set
        {
            FooImplementation = value ? new EnabledFoo() : new DisabledFoo()
        }
    }

    public void Bar() {
        FooImplementation.Bar();
    }
    public void Baz() {
        FooImplementation.Baz();
    }
    public void Bat() {
        FooImplementation.Bat();        
    }
}

internal class EnabledFoo : IFoo {
    public void Bar() {
        //...
    }
    public void Baz() {
        //...
    }
    public void Bat() {
        //...
    }
}

internal class DisabledFoo : IFoo {
    public void Bar() {}
    public void Baz() {}
    public void Bat() {}
}

And if your intent is to mock the foo implementation for unit testing, just drop the FooIsEnabled property and make FooImplementation public. In this case you should also get rid of DisabledFoo, and test using an instance such as:

var fooImplementationMock = new Mock<IFoo>();
var foo = new Foo { FooImplementation = fooImplementationMock.Object };
foo.Bar();
fooImplementationMock.Verify(f => f.Bar());

given you are using moq.