Prevent method execution and property and variable access/modification - c#

I am unexperienced with Aspect-Oriented Programming. However, I've read a fair amount of PDFs and documentation available from PostSharp, and I think that I understand the gist of the paradigm. I have a pretty unique problem, and I believe AOP can be used to solve it. My predicament is as follows:
Many classes will inherit from A, which can be enabled or disabled. Consider B, which extends A. If B is disabled, I would like all method execution and property and variable access/modification to be disabled. That is, B.ExecuteMethod(); and B.Property = newValue; will have no effect if B is disabled. Furthermore, if one expects a return value, the value will be defaulted to 0 or null if B is disabled. That is, I would like to have expected default values for objects and values.
I am using the PostSharp C# library, which seems very powerful and well-developed. I believe my problem can be solved by means of AttributeInheritance. For example, A can be defined as:
[ModularAttribute(AttributeInheritance = MulticastInheritance.Multicast)]
public class A {
private bool m_enabled;
public A(){
m_enabled = true;
}
public bool Enabled() {
get {
return m_enabled;
}
set {
m_enabled = value;
}
}
}
and B can extend A. Moreover, my attribute, ModularAttribute can be defined as:
[Serializable]
public sealed class ModularAttribute : OnMethodBoundaryAspect {
public ModularAttribute() {
}
public override void OnEntry(MethodExecutionArgs args) {
// only execute code if enabled
}
}
This attribute will be applied to B because B extends A.
The root of my problem is: I need ModularAttribute to reference A's Enabled property, such that OnEntry will only execute code if Enabled is true. Since this is a class-level aspect, I cannot parameterize a wrapped version of m_enabled to ModularAttribute since it is out of scope.
Is there a way that I can tell ModularAttribute that all of its owners will implement a specific interface? If so, could ModularAttribute access the specific properties from said interface? If so, this would solve my problem.
To clarify, I would like to "tell" PostSharp: "The class that uses ModularAttribute is guaranteed to implement C. So, let ModularAttribute access whatever C defines because it's ensured to work."
C can be defined as:
public interface C {
public bool Enabled();
}
Thus, in ModularAttribute, I could do something along the lines of
if (attachedClass.Enabled == false) {
// don't execute code
} else {
// execute code
}
This problem can be perceived as authentication on the per-object level rather than the more typical per-user level. Having to add an if, else check on every Property and Method that extends A seems like a cross-cutting concern. Thus, I think AOP is a fitting choice for this problem; however, because of my inexperience with this paradigm, I might be approaching it the wrong way.
Any guidance would be much appreciated. Thanks for the help,

I'm a little concerned that this much inheritance could be a design flaw or at least a huge maintenance headache, but assuming that it's not, let's soldier on...
I don't think there's a way to do exactly what you want to do. Even if PostSharp had the ability, C# needs to know the type at compile time (before PostSharp even touches it).
I suggest that you use CompileTimeValidate to verify that the class the aspect is used on is of a certain type, and once that's in place, you can cast args.Instance to your interface type without worrying about an invalid cast exception. And if that class doesn't implement IEnabled, then you'll get a compile-time error.
Here's a quick example:
public interface IEnabled
{
bool Enabled { get; }
}
[Serializable]
public class ModularAttribute : OnMethodBoundaryAspect
{
public override bool CompileTimeValidate(System.Reflection.MethodBase method)
{
if(typeof(IEnabled).IsAssignableFrom(method.DeclaringType))
return true;
Message.Write(method, SeverityType.Error, "MYERR001", "Aspect can't be used on a class that doesn't implement IEnabled");
return false;
}
public override void OnEntry(MethodExecutionArgs args)
{
var obj = (IEnabled) args.Instance; // this will always be a safe cast
if(!obj.Enabled)
args.FlowBehavior = FlowBehavior.Return;
}
}
There's a catch though: you don't want this aspect being used on the Enabled property itself, because that would cause a stack overflow (i.e. the aspect checks the property, causing the aspect to check the property, etc). So make sure to exclude Enabled using AttributeExclude.
class Program
{
static void Main(string[] args)
{
var b = new B();
b.Enabled = false;
b.SomeMethod();
b.AnotherMethod();
}
}
public interface IEnabled
{
bool Enabled { get; }
}
[Modular(AttributeInheritance = MulticastInheritance.Multicast)]
public class A : IEnabled
{
[Modular(AttributeExclude = true)]
public bool Enabled { get; set; }
public void SomeMethod()
{
Console.WriteLine("in SomeMethod");
}
}
public class B : A
{
public void AnotherMethod()
{
Console.WriteLine("in AnotherMethod");
}
}

Related

Is it possible to restrict public enum values in C#?

I am currently writing a software program for a tour, made up of exhibits. The exhibit object, at any given point, is in one of four states, defined by the ExhibitStates enum:
private enum ExhibitState { Ready, Active, Complete, Inactive };
For developers who will be setting up exhibits, there are only two "starting" states that I want them to be able to choose from:
public enum StartingExhibitState { Ready, Inactive };
Currently, I have it set up so that upon being initialized, the exhibit will immediately set its state to match its starting state, like so:
switch (startingState) {
case StartingExhibitState.Ready:
SetState(ExhibitState.Ready);
break;
case StartingExhibitState.Inactive:
SetState(ExhibitState.Inactive);
break;
}
I found myself wondering today if this was the best practice. Is there a better way to restrict which enum options are public and which are private? Or is it best to simply have the two separate enums?
Thank you so much for your time.
If you create second enum - your intents will be very clearly explained through signature of setting method
public enum ExhibitState
{
Inactive = 0,
Active = 1,
Ready = 2,
Complete = 3
};
public enum InitialStates
{
Inactive = ExhibitState.Inactive,
Ready = ExhibitState.Ready
};
public void SetInitial(InitialStates state)
{
SetState((ExhibitState)state);
}
If you go further you can add compiler help for preventing passing wrong values to the method.
public sealed class InitialState
{
public static readonly InitialState Initial = new InitialState(ExhibitState.Initial);
public static readonly InitialState Ready = new InitialState(ExhibitState.Ready);
public ExhibitState State { get; }
private InitialState(ExhibitState state)
{
State = state;
}
}
Constructor made private to prevent instantiating class from else where.
Class marked as sealed to prevent deriving and changing it behaviour.
Then your method will look like
public void SetInitial(InitialState start)
{
SetState(start.State);
}
// use it
SetInitial(InitialState.Initial);
SetInitial(InitialState.Ready);
Nothing else cannot be passed, until you change code of InitialState class.
Instead of using an enum (or two of them), you could use a class-based approach:
public abstract class ExhibitState
{
public static ExhibitInitialState Ready { get { return new ExhibitReadyState(); } }
public static ExhibitInitialState Inactive { get { return new ExhibitInactiveState(); } }
public static ExhibitState Complete { get { return new ExhibitCompleteState(); } }
public static ExhibitState Active { get { return new ExhibitActiveState(); } }
private class ExhibitReadyState : ExhibitInitialState {}
private class ExhibitInactiveState : ExhibitInitialState {}
private class ExhibitCompleteState : ExhibitState {}
private class ExhibitActiveState : ExhibitState {}
}
public abstract class ExhibitInitialState : ExhibitState {}
The above sample shows a simple approach. Usually, you'd not create a new instance of a state in the get methods, but have static instances so that comparing is easier.
Similar to an enum, you could still type ExhibitState.Ready or the other states. In addition, the base class ExhibitInitialState allows you to limit the states that can be set initially:
public void SetInitial(ExhibitInitialState initState) { ... }
In comparison to the approach that #Fabio proposed, you'd have the benefit that you could not mix up the values. Furthermore and especially relevant for states: is very common that the behavior should also change for a specific state. With this class-based approach, you could implement this behavior in the specific ExhibitState implementations and by that avoid lots of switch statements that are likely to exist in an enum-based approach.

Raising warnings based on class attributes

Here is some code:
class Program
{
static void Main(string[] args)
{
MyClass class1 = new MyClass();
MyOtherClass class2 = new MyOtherClass();
Helper.UseAttribute<MyClass>(class1);
//Raise a warning to tell the developer that they cannot use this class
//as there is no property with the specified attribute.
Helper.UseAttribute<MyOtherClass>(class2);
}
}
public class MyAttribute : System.Attribute { }
class MyClass
{
[MyAttribute]
public string SomethingAwesome { get; set; }
}
class MyOtherClass
{
public string SomethingElseWhichIsAlsoPrettyAwesome { get; set; }
}
static class Helper
{
public static void UseAttribute<T>(T sender)
{
//Do something with the property that has MyAttribute
//If there isn't a property with this attribute, then raise
//a warning.
}
}
In an ideal scenario, I want to restrict a developer from passing classes to a method which do not have a certain attribute.
I am aware that I can use an interface, or a base class of some description, however the question really is whether something like the example above is possible.
If you're happy to either use the VS 2015 preview or wait until VS 2015 is out, you can use Roslyn for this.
You'd write a DiagnosticAnalyzer class, probably registering a syntax node analyzer to specifically look for invocations of Helper.UseAttribute<T>. When you find such a use, you'd find the symbol for T and check whether there are any properties with the MyAttribute attribute applied to it, and raise a warning if not. This warning will be shown in Visual Studio itself, as well as applying on CI builds (assuming you register the analyzer assembly appropriately).
It takes a while to get started with the Roslyn diagnostic APIs, but once you're used to it, it's really powerful.
Of course, another option is to throw an exception at execution time, and rely on there being unit tests around all callers so that you'd be able to catch it when they fail :) You should probably do that as well as adding compile-time support via Roslyn.
Best you can do right now is to handle it on runtime (and throw an exception or something). On design-/compiletime I think there is no possibility yet.
public static void UseAttribute<T>(T sender)
{
var hasAttribute = typeof(T).GetProperties().Any(prop => Attribute.IsDefined(prop, typeof(MyAttribute)));
if (!hasAttribute)
throw new Exception("Does not contain attribute");
}

Method overriding or interception

In my project, I have many DLL assemblies referenced. One of those DLL's contains the bool method that I want to change. I do not have the original source for the DLL and using a Reflector to decompile a project seems impractical. All I want to do is intercept or override this method or method call so that I can change it's return value to match my own method outside of said DLL.
Any such way to do this? Thanks!
Edit:
Here is an example:
public virtual bool isOwner()
{
return false;
}
Essentially, I just want to change getOwner to return true;
If the class is public and the method is marked as virtual, then you can simply override it with this syntax:
public MyClass : TheClass
{
public override ReturnType MethodName(Arguments)
{
//class the base class implementation if needed
//base.MethodName(Arguments)
//do your own stuff and return whatever is needed
}
}
Hope this helps
EDIT: A word of caution though, this won't replace the calling code within the DLL. It will only work if you instantiate the derived class yourself and call it from your code.
Is there a general way to do what you want, built into .NET?
Yes, and no.
If you want every usage of class X' method Y to be replaced by some other code, then no, there is nothing built into .NET class system or compiler that will do this.
If you can inherit from class X, overriding method Y, and then ensure that all places where class X is used, your new class is used instead, then yes, that is the proper way to do this.
This is easily done:
public class YourFixedClass : TheProblematicClass
{
public override string YourProblematicMethod()
{
// probably call the problematic method through base.
// and fix the return value, or fix the parameters
// or don't call it at all, re-doing whatever it does
}
}
Or, if you can make a new class that implements all the same interfaces, wrapping (delegating) all the methods and properties of the original (problematic) class, then that might be doable, but this requires all actual usage of the class to go through the interfaces.
As this:
public class Wrapper : IInterface1, IInterface2
{
private readonly YourProblematicClass _C;
public Wrapper(YourProblematicClass c)
{
_C = c;
}
public string YourProblematicMetho()
{
// probably call the problematic method through _C.
// and fix the return value, or fix the parameters
// or don't call it at all, re-doing whatever it does
}
}
If, on the other hand, you don't have control of where all the code is that calls the class/method, then no, you can't do any of this.
So what else is there? Well, there is always the debugger interfaces. You can make a program that is somehow the debugger of itself, patching in the right code upon demand, but this is likely to be extraordinary difficult to get right.
In short, no, there is no way to do what you want. You need to find a different way to accomplish this.
Have you thought about changing the original assembly in the first place? I understand that you don't have the source code for it, but is that because:
You lost it
You didn't make it
In point 1, I would really work towards recreating the source code, either through a decompiler or similar, and get a new project going to fix that.
In point 2, have you thought about contacting the people that made it and asking them for help?
Uhm Ok you can do something like this:
public class MyNameClass : MyDllname.MyClassName
{
public bool isOwner()
{
return !base.isOwner();
}
}
Then you have override the method and you can use all the other methods in the DLL simply using an istance(if there aren't static) of the MyNameClass
You can use "new" modifier.
See example on http://msdn.microsoft.com/en-us/library/435f1dw2.aspx
Or this:
class Program
{
static void Main(string[] args)
{
Console.WriteLine(new ClassA().IsEvenDayToday()); // Result: true
Console.WriteLine(new ClassB().IsEvenDayToday()); // Result: false
Console.ReadKey();
}
}
public class ClassA : ClassB
{
public new bool IsEvenDayToday()
{
return DateTime.Now.Day % 2 == 0;
}
}
public class ClassB
{
public bool IsEvenDayToday()
{
return DateTime.Now.Day % 2 != 0;
}
}

Which is best for perfomance?

Which of the following code snippets performs fastest?
if(ClassTestBase is ClassTestChild1)
or
if(ClassTestBase.Type == EClassType.Child1)
Update:
Here is the full scenario:
public enum EInheritanceTree
{
BaseClass,
Child1,
Child2,
Child3
}
public class MyBaseClass
{
public virtual EInheritanceTree MyClassType
{
get
{
return EInheritanceTree.BaseClass;
}
}
}
public vlasse MyChildClass1 : MyBaseClass
{
public override EInheritanceTree MyClassType
{
get
{
return EInheritanceTree.Child1;
}
}
}
Consider a method that has to compare the class type to see what kind it is. Which is the best?
public bool IsChild1(MyBaseClass myClass)
{
if(myClass is MyChildClass1)
return true;
return false;
}
or
public bool IsChild1(MyBaseClass myClass)
{
if(myClass.MyClassType == EInheritanceTree.Child1)
return true;
return false;
}
Have you thought about using a profiler to test which is more performant yourself? Visual Studio comes with a profiler.
I would be more concerned about the need to have an enum that hold inheritance information about your application.
If you're worried about performance, don't wrap all this in functions. Any code that says:
if (Obj.IsChild1() ) foo;
Should just do:
if(myClass.MyClassType == EInheritanceTree.Child1) foo;
If you're worried about the performance, any notions you may have that says to hide everything behind functions needs to be revisited. Also, why don't you just use polymorphism - that's the "right" way to make subclasses act differently.
Regardless, do some timing of your own. It's the only way to be certain which is faster.

How can one type access a private setter of another type's property?

All I need is a way to make a property of one class only 'settable' from one other class (a sort of manager class).
Is this even possible in c#?
My colleague 'reliably' informs me that I have a design flaw, but I feel I should at least ask the community before I concede defeat!
No, it's not really possible to do this in any clean way in C#. You probably have a design flaw ;-)
You can use the internal modifier, which lets all types in the same assembly access the data (or nominated assemblies if using [InternalsVisibleTo] - but no: there is no friend equivalent in C#.
For example:
public string Foo {get; internal set;}
You have a design flaw. Also, don't be paranoid about data hiding. Here's 3.5's way to do it:
class Program
{
static void Main(string[] args)
{
Managed m = new Managed();
Console.WriteLine(m.PrivateSetter);
m.Mgr.SetProperty("lol");
Console.WriteLine(m.PrivateSetter);
Console.Read();
}
}
public class Managed
{
private Manager _mgr;
public Manager Mgr
{
get { return _mgr ?? (_mgr = new Manager(s => PrivateSetter = s)); }
}
public string PrivateSetter { get; private set; }
public Managed()
{
PrivateSetter = "Unset";
}
}
public class Manager
{
private Action<string> _setPrivateProperty;
public Manager(Action<string> setter)
{
_setPrivateProperty = setter;
}
public void SetProperty(string value)
{
_setPrivateProperty(value);
}
}
Here's how we'd do it in pre-lambda days:
public class Managed
{
private Manager _mgr;
public Manager Mgr
{
get { return _mgr ?? (_mgr = new Manager(this)); }
}
public string PrivateSetter { get; private set; }
public Managed()
{
PrivateSetter = "Unset";
}
public class Manager
{
public void SetProperty(string value)
{
m.PrivateSetter = value;
}
private Managed m;
public Manager(Managed man)
{
m = man;
}
}
}
The best way to do it would be:
/// <summary>
/// Gets or sets foo
/// <b>Setter should only be invoked by SomeClass</b>
/// </summary>
public Object Foo
{
get { return foo; }
set { foo = value; }
}
When you have some complex access or inheritance restriction, and enforcing it demands too much complexity in the code, sometimes the best way to do it is just properly commenting it.
Note however that you cannot rely on this if this restriction has some security implications, as you are depending on the goodwill of the developer that will use this code.
You cannot do that on that way, but you can access a property's setter method from a derived class, so you can use inheritance for the purpose. All you have to do is to place protected access modifier. If you try to do so, your colleague is right :). You can try doing it like this:
public string Name
{
get{ return _name; }
protected set { _name = value; }
}
keep in mind that the set method of the property is only accessible from the derived class.
Or you could have these two classes in an assembly alone and have the setter as internal. I would vote up for the design flaw though, unless the previous answer by milot (inheriting and protected) makes sense.
You could do:
public void setMyProperty(int value, Object caller)
{
if(caller is MyManagerClass)
{
MyProperty = value;
}
}
This would mean that you could use a 'this' pointer from the calling class. I would question the logic of what you're attempting to achieve, but without knowing the scenario I can't advise any futher. What I will say is this: if it is possible to refactor your code to make it clearer, then it is often worthwhile doing so.
But this is pretty messy and certinly NOT fool-proof ... you have been warned!
Alternativly...
You could pass a delegate from the Class with the Property (Class A) to the Manager Class (Class B). The delegate can refer to a private function within A to allow B to call that delegate as any normal function. This precludes that A knows about B and potentially that A is created before B. Again... messy and not fool-proof!
You can achieve to this by making a Public property in your "settable class" that will inherit from the real class that will have a protected property... this way only the inherit class can SET and not class that doesn't inherit. But the drawback is that you will require to have an inherit class...
Reflection, though I would agree that having to do this just to get around an access modifier is probably an indication of a bad design.
public class Widget
{
private int count;
public int Count
{
get { return this.count; }
private set { this.count = value; }
}
}
public static class WidgetManager
{
public static void CatastrophicErrorResetWidgetCount( Widget widget )
{
Type type = widget.GetType();
PropertyInfo info = type.GetProperty("Count",BindingFlags.Instance|BindingFlags.NonPublic);
info.SetValue(widget,0,null);
}
}
The reason this is a design flaw is because it seems muddled between the scope of the two objects.
The properties of a class should be accessible in the context of that class, at least internally.
It sounds like the settable property on your item class is really a property of the manager class.
You could do something similar to what you want by closely coupling the two classes:
public class MyItem {
internal MyItemManager manager { get;set; }
public string Property1 {
get { return manager.GetPropertyForItem( this ); }
}
}
Unfortunately this isn't great design either.
What your looking for is what C++ calls a Friend class but neither c# or vb has this functionality. There is a lot of debate as to the merit of such functionality since it almost encourages very strong coupling between classes. The only way you could implement this in c# would be with reflection.
If your goal is to have a class Foo let some property (e.g. Bar, of type Biz) to be changed by some other object, without exposing it publicly, a simple way to do that is to have an instance of Foo which is supposed to be changeable by some other object to pass that other object an Action<Biz> which points to a private method that changes Bar to the passed-in value. The other object may use that delegate to change the Bar value of the object that supplied it.
If one wishes to have give all instances of some type Woozle the ability to set the Bar value of any instance of Foo, rather than exposing such abilities on a per-instance basis, one may require that Woozle have a public static method Woozle.InstallFooBarSetter which takes a parameter of type Action<Foo, Biz> and one of type Object. Foo should then have a static method WoozleRequestBarSetter which takes an Object, and passes it to Woozle.InstallFooBarSetter along with an Action<Foo,Biz>. The class initializer for Woozle should generate a new Object, and pass it to Foo.RequestBarSetter; that will pass the object to Woozle.InstallFooBarSetter along with a delegate. Woozle can then confirm that the passed-in object is the one that it generated, and--if so--install the appropriate delegate. Doing things this way will ensure that nobody but Woozle can get the delegate (since the delegate is only passed to Woozle.InstallFooBarSetter), and Woozle can be sure its delegate comes from Foo (since nobody else would have access to the object that Woozle created, and Woozle.InstallFooBarSetter won't do anything without it).
if it is a design flaw depends on what you want to do. You could use the StackTrace class from System.Diagnostics to get the Type of the class setting your property and then compare to the type you want to allow setting yor property..but maybe there are better ways for performing something like this (e.g. boxing)

Categories