I'm wondering if there's a way to hook to an event whenever an object is instantiated.
If it doesn't, is there a way to retrieve the object to which an attribute is attached to when the attribute is instantiated?
What I want to do is give some of my classes a custom attribute and whenever a class with this attribute is instantiated, run some code for it.
Of course, I could simply place the code in each of those classes' constructor but that's a lot of copy and pasting and I could easily forget to copy that code into one or two classes. And of course, would be very convenient for end users as all they would have to do is add my attribute to their classes and not worry about remember to add that bit of code in their constructors.
I actually can't do a base class because all of those objects already have a base.
Thanks in advance.
Here's an example of what I'd like to do. Either use the attribute's constructor or have an event handler for object instantiation.
public class MySuperAttribute : Attribute
{
public MySuperAttribute()
{
//Something akin to this or the event in Global
Global.AddToList(this.TheTargetObject);
}
}
[MySuperAttribute]
public class MyLabel : System.Windows.Forms.Label
{
}
public static class Global
{
public static void AddToList(Object obj)
{
//Add the object to a list
}
//Some pseudo-hook into the instantiation of any object from the assembly
private void Assembly_ObjectInstantiated(Object obj)
{
if(obj.GetType().GetCustomAttributes(typeof(MySuperAttribute), true).Count != 0)
AddtoList(obj);
}
}
There is no easy way to hook object instantiation externally, maybe with some debugging API, and it has a good reason. It makes your code harder to maintain and understand for other people.
Attributes won't work, because the instance of an attribute is not actually created until it is required - via reflection, and an attribute is assigned to a type, not an instance.
But you may well put the code in a base class, and derive all other classes from it, although it is also not a good practice to pass half-initialized instance to other methods. If the class inherits from ContextBoundObject, you can assign a custom implementation of ProxyAttribute to it and override all operations on it.
If you can't create a common base class (when your types inherit from different types), you can always create the instance with a custom method like this one:
public static T Create<T>() where T : new()
{
var inst = new T();
Global.AddToList(inst);
return inst;
}
However, seeing as you inherit from form controls, their instantiation is probably controlled by the designer. I am afraid there is no perfect solution, in this case.
Related
I was unclear in an earlier question I ask so I will try to be more explicit.
Is there a way to put a static class inside of a dictionary so that its functions can be called? If this is not possible, what is the best alternative that doesn't involve using instances that you can suggest?
Here is how I would like to use it:
static class MyStatic : IInterface
{
static void Do(){}
}
static class MyStatic2 : IInterface
{
static void Do(){}
}
class StaticMap
{
static Dictionary<Type,IInterface.class> dictionary = new Dictionary<Type,IInterface.class>
{
{Type.1, MyStatic}
{Type.2, MyStatic2}
};
}
// Client Code
class ClientCode
{
void Start()
{
StaticMap.dictionary[Type.1].Do();
}
}
There are some fundamental reasons why you can't do that directly:
Static method calls are bound at compile-time
Static calls are not inherited - they are tied to the class that defines them
There is no implicit base type (and therefore no polymorphism) between static methods, even if the name, inputs, and outputs are all the same
Since your signature is the same for every static method, you could store a Action in the dictionary instead:
static Dictionary<Type,Action> dictionary = new Dictionary<Type,Action>
{
{Type.1, MyStatic.Do}
{Type.2, MyStatic2.Do}
};
then you can call the Action directly:
void Start()
{
StaticMap.dictionary[Type.1]();
}
It's slightly repetetive because you have to specify the method name in the dictionary as well, but it's type safe.
A key question is whether you want to call a single method on each type or whether you need to call multiple methods belonging to each type.
If it's just a single method, then what D Stanley suggested is the answer. If you store a number of Actions, each representing a method with the same signature on a different static class, then you're accomplishing what you said.
However that raises a question - why the constraint that each method must belong to a separate static class? This approach would work just as well if some or all of the methods belonged to the same class.
If you need to call more than one method from each class then an Action no longer works. You'd have to store collections of Action, which a) means class instances, and b) is a lot more complicated than just using interfaces and class instances.
One way to manage instances is by using a dependency injection container to create class instances for you. Using that approach, you can create non-static classes without having to go through the hassle of explicitly making them singletons. But you can tell the container to only produce one of each and reuse it. For example, using Castle Windsor:
container.Register(Component.For<ISomeInterface,SomeClass>));
Now every time the container is asked to provide an instance of ISomeInterface it will always provide the same instance of SomeClass.
Because the dependency you're looking for varies by type (Dictionary<Type, Something>) it sounds like what you're looking for might be related to generics. But it would be necessary to take a step back from the smaller problem and understand a slightly larger picture of what you're trying to accomplish.
Instead of having the entire class as static, create a Singleton instance.
public class Foo
{
public static Foo _Foo;
public Foo()
{
_Foo = this;
}
}
Then you may add it to your list, and also inherit from Interfaces, etc.
I have a good complete class which is doing awesome things. I need to allow users to use this class by replacing some methods in it, but inheritance is not allowed, because this class also used in other application classes.
It is like you have a class which creating a table, but you need to allow users to redefine method which is creating table cell to let the user print something custom in this cell. The class, however, has a default way to print the cell content (in case the user do not need to customize it).
Is there any common-used or standartized way to achieve this?
Updated
Having had "the peanut gallery" point out that my approach (at bottom) wouldn't fit the bill, here's another way:
Use delegation. Define certain public properties with type Action or Func. Where these behaviors need to be invoked in your code, compare the properties to null. If null, use your default behavior. If not, invoke the values.
Your calling code MAY set the properties, but doesn't have to.
(first try) Alternative approaches:
You are describing an extension method, or the use of inheritance if that's available.
Extension methods enable you to "add" methods to existing types without creating a new derived type, recompiling, or otherwise modifying the original type. Extension methods are a special kind of static method, but they are called as if they were instance methods on the extended type. For client code written in C# and Visual Basic, there is no apparent difference between calling an extension method and the methods that are actually defined in a type.
https://msdn.microsoft.com/en-us//library/bb383977.aspx
Inheritance, together with encapsulation and polymorphism, is one of the three primary characteristics (or pillars) of object-oriented programming. Inheritance enables you to create new classes that reuse, extend, and modify the behavior that is defined in other classes. The class whose members are inherited is called the base class, and the class that inherits those members is called the derived class. A derived class can have only one direct base class. However, inheritance is transitive. If ClassC is derived from ClassB, and ClassB is derived from ClassA, ClassC inherits the members declared in ClassB and ClassA.
https://msdn.microsoft.com/en-us/library/ms173149.aspx
You can't derive from all .NET types, but you can write extension methods for them.
Assuming you are able to modify the existing class, you should be marking your method as virtual.
This will allow you to provide a default implementation (which is what your existing code will use) and be able to override it with a custom one where needed.
Your base class could be something along the lines of:
public class TableMaker
{
public virtual string MakeTable()
{
//Provide default implementation used by existing code here
}
}
Your inheriting class can then override the virtual method:
public class SpecialTableMaker : TableMaker
{
public override string MakeTable()
{
//Provide specific implementation for cell text here
}
}
You existing code will work just fine and you can use this other class where you need it.
I've finally ended with this solution. It was proposed by #codenoir, however I also have a code which demonstrates a whole mechanism.
public class MyTable
{
public delegate string OnInsertHandler();
public event OnInsertHandler OnInsert;
public string Show()
{
string res = "-BEGIN-";
if (OnInsert != null) {
res += OnInsert ();
} else {
res += "#default insert#";
}
res += "-END-";
return res;
}
}
public class DelegateTester
{
public void OnTest()
{
MyTable mt = new MyTable();
Debug.Log("Default output: " + mt.Show()); // Shows "-BEGIN-#default insert#-END-"
// Changing functionality via delegate
mt.OnInsert += MyCustomInsert;
Debug.Log("Customized output: " + mt.Show()); // Shows "-BEGIN-#custom insert#-END-"
// Remove delegate
mt.OnInsert -= MyCustomInsert;
Debug.Log("Rollbacked output: " + mt.Show()); // Shows "-BEGIN-#default insert#-END-"
}
public string MyCustomInsert()
{
return "#custom insert#";
}
}
In this example I am using MyTable class which is extended using Func delegate. This way I can allow to users of my software module to extend only one method without make any mess with others classes and objects.
In building a class structure, I would like to have derived classes potentially posses derived member classes. For example:
class GamePiece
{
}
class Checker : GamePiece
{}
class ChessMan : GamePiece
{}
class Game
{
protected GamePiece _piece;
}
class Checkers : Game
{
Checkers(){ _piece = new Checker(); }
}
class Chess : Game
{
Chess(){_piece = new ChessMan();}
}
This is seriously oversimplified, but makes the actual point. Now assuming that there are events and such, I would like to attach the common ones in the base class constructor, and the specialized ones in the derived constructor. For example both a checker and a chessman might have a "captured" event and a "moved" event. I would like to attach them in the base constructor. However, events that would be specific such as "castled" or something like that would be attached only in the specific constructor.
The problem I have is that the base constructor seems to only be able to run BEFORE the derived constructor. How do I effect this such that I get to actually instantiate the "gamepiece" before I call the base "Game" constructor to attach to events.
My gut suggests that this is better handled by removing that functionality from the constructor and simply having an "Attach()" member function and handling it there. However, I want to make sure I am going in the right direction, since it would seem there should be a way to do it in the constructor.
You can try injecting it from child to parent, like this:
abstract class Game {
protected GamePiece _piece;
protected Game(GamePiece piece)
{
_piece = piece;
// do the common work with pieces here
}
}
class Checkers : Game
{
public Checkers(Checker piece) : base(piece)
{
// piece-specific work here
}
}
If you need more complicated work done than just instantiating, you could create a static factory method that did all the work, and just call that when invoking the base constructor. This does change your Game implementation slightly in ways that change how you instantiate it, but that can be solved by using a factory object anywhere you need a new Game.
Edit: I actually realized the original code-sample I posted wasn't correct; there was no way to reference the Checker piece (as a Checker) in the Checkers class. But if you inject the Checker piece into that as well, the problem is solved and you have your reference. This is dependency injection, by the way.
You could try the Template design pattern:
class Game
{
Game() { Init(); }
protected virtual void Init() {}
}
Now you can insert generic event handling in the Game Init method and override it with concrete handling logic in the descendants.
For instance, if I have a class like this:
namespace Sample
{
public Class TestObject
{
private Object MyAwesomeObject = new MyAwesomeObject();
}
}
Is there any benefit to set it up so that the property is set in the constructor like this?
namespace Sample
{
public Class TestObject
{
private Object MyAwesomeObject;
public TestObject()
{
MyAwesomeObject = new MyAwesomeObject()
}
}
}
The two are (nearly) identical.
When you define the initializer inline:
private Object MyAwesomeObject = new MyAwesomeObject();
This will happen prior to the class constructor code. This is often nicer, but does have a couple of limitations.
Setting it up in the constructor lets you use constructor parameters to initialize your members. Often, this is required in order to get more information into your class members.
Also, when you setup values in your constructors, you can use your class data in a static context, which is not possible to do with inlined methods. For example, if you want to initialize something using an expression tree, this often needs to be in a constructor, since the expression tree is in a static context, which will not be allowed to access your class members in an inlined member initializer.
It makes it easier to do step by step debugging
It makes it easier to control the order in which you call constructors
It makes it possible to send parameters to the constructors based on some logic or passed in argument to the object you are working on.
Another nice property of initializing stuff at the declaration site is that doing so on readonly fields guarantees that the field is not observable in its default (initiaized to zero) state.
Here's my article on the subject:
http://blogs.msdn.com/ericlippert/archive/2008/02/18/why-do-initializers-run-in-the-opposite-order-as-constructors-part-two.aspx
The only benefit is that you can be a bit more dynamic in the constructor, where inline initialization requires that you only use static values for constructor arguments and such. For example, if MyAwesomeObject needs the value from a config file, you would have to set that in the constructor
Fields are initialized immediately
before the constructor for the object
instance is called. If the constructor
assigns the value of a field, it will
overwrite any value given during field
declaration.
See Fields (C# Programming Guide).
In your particular example, there's no advantage.
There is, however, lazy instantiation, which reduces your memory footprint in many cases:
namespace Sample
{
public Class TestObject
{
private Object m_MyAwesomeObject;
public TestObject()
{
}
public Object MyAwesomeObject
{
get
{
if (m_MyAwesomeObject == null)
m_MyAwesomeObject = new Object();
return m_MyAwesomeObject;
}
}
}
}
I like to keep all initialization for any class property whether primitive or object in the class constructor(s). Keeps the code easier to read. Easier to debug. Plus the intention of a constructor is to initialize your classes properties.
Also for clients developing against your classes it's nice to make sure that all your properties get a default value and all objects get created. Avoids the NullReferenceExceptions, when a client is using your class. For me putting this all in constructors makes it easier to manage.
I do not like to duplicate code, even if it is among a (hopefully) small number of constructors. To that end I tend to favor inline initialization wherever it makes sense.
Generally, requiring a non-default constructor ensures that the instance is in something other than the default state. This also allows immutable classes, which have their own advantages.
Let's assume that our system can perform actions, and that an action requires some parameters to do its work.
I have defined the following base class for all actions (simplified for your reading pleasure):
public abstract class BaseBusinessAction<TActionParameters>
: where TActionParameters : IActionParameters
{
protected BaseBusinessAction(TActionParameters actionParameters)
{
if (actionParameters == null)
throw new ArgumentNullException("actionParameters");
this.Parameters = actionParameters;
if (!ParametersAreValid())
throw new ArgumentException("Valid parameters must be supplied", "actionParameters");
}
protected TActionParameters Parameters { get; private set; }
protected abstract bool ParametersAreValid();
public void CommonMethod() { ... }
}
Only a concrete implementation of BaseBusinessAction knows how to validate that the parameters passed to it are valid, and therefore the
ParametersAreValid is an abstract function. However, I want the base class constructor to enforce that the parameters passed are always valid, so I've added a
call to ParametersAreValid to the constructor and I throw an exception when the function returns false. So far so good, right? Well, no.
Code analysis is telling me to "not call overridable methods in constructors" which actually makes a lot of sense because when the base class's constructor is called
the child class's constructor has not yet been called, and therefore the ParametersAreValid method may not have access to some critical member variable that the
child class's constructor would set.
So the question is this: How do I improve this design?
Do I add a Func<bool, TActionParameters> parameter to the base class constructor? If I did:
public class MyAction<MyParameters>
{
public MyAction(MyParameters actionParameters, bool something) : base(actionParameters, ValidateIt)
{
this.something = something;
}
private bool something;
public static bool ValidateIt()
{
return something;
}
}
This would work because ValidateIt is static, but I don't know... Is there a better way?
Comments are very welcome.
This is a common design challenge in an inheritance hierarchy - how to perform class-dependent behavior in the constructor. The reason code analysis tools flag this as a problem is that the constructor of the derived class has not yet had an opportunity to run at this point, and the call to the virtual method may depend on state that has not been initialized.
So you have a few choices here:
Ignore the problem. If you believe that implementers should be able to write a parameter validation method without relying on any runtime state of the class, then document that assumption and stick with your design.
Move validation logic into each derived class constructor, have the base class perform just the most basic, abstract kinds of validations it must (null checks, etc).
Duplicate the logic in each derived class. This kind of code duplication seems unsettling, and it opens the door for derived classes to forget to perform the necessary setup or validation logic.
Provide an Initialize() method of some kind that has to be called by the consumer (or factory for your type) that will ensure that this validation is performed after the type is fully constructed. This may not be desirable, since it requires that anyone who instantiates your class must remember to call the initialization method - which you would think a constructor could perform. Often, a Factory can help avoid this problem - it would be the only one allowed to instantiate your class, and would call the initialization logic before returning the type to the consumer.
If validation does not depend on state, then factor the validator into a separate type, which you could even make part of the generic class signature. You could then instantiate the validator in the constructor, pass the parameters to it. Each derived class could define a nested class with a default constructor, and place all parameter validation logic there. A code example of this pattern is provided below.
When possible, have each constructor perform the validation. But this isn't always desirable. In that case, I personally, prefer the factory pattern because it keeps the implementation straight forward, and it also provides an interception point where other behavior can be added later (logging, caching, etc). However, sometimes factories don't make sense, and in that case I would seriously consider the fourth option of creating a stand-along validator type.
Here's the code example:
public interface IParamValidator<TParams>
where TParams : IActionParameters
{
bool ValidateParameters( TParams parameters );
}
public abstract class BaseBusinessAction<TActionParameters,TParamValidator>
where TActionParameters : IActionParameters
where TParamValidator : IParamValidator<TActionParameters>, new()
{
protected BaseBusinessAction(TActionParameters actionParameters)
{
if (actionParameters == null)
throw new ArgumentNullException("actionParameters");
// delegate detailed validation to the supplied IParamValidator
var paramValidator = new TParamValidator();
// you may want to implement the throw inside the Validator
// so additional detail can be added...
if( !paramValidator.ValidateParameters( actionParameters ) )
throw new ArgumentException("Valid parameters must be supplied", "actionParameters");
this.Parameters = actionParameters;
}
}
public class MyAction : BaseBusinessAction<MyActionParams,MyActionValidator>
{
// nested validator class
private class MyActionValidator : IParamValidator<MyActionParams>
{
public MyActionValidator() {} // default constructor
// implement appropriate validation logic
public bool ValidateParameters( MyActionParams params ) { return true; /*...*/ }
}
}
If you are deferring to the child class to validate the parameters anyway, why not simply do this in the child class constructor? I understand the principle you are striving for, namely, to enforce that any class that derives from your base class validates its parameters. But even then, users of your base class could simply implement a version of ParametersAreValid() that simply returns true, in which case, the class has abided by the letter of the contract, but not the spirit.
For me, I usually put this kind of validation at the beginning of whatever method is being called. For example,
public MyAction(MyParameters actionParameters, bool something)
: base(actionParameters)
{
#region Pre-Conditions
if (actionParameters == null) throw new ArgumentNullException();
// Perform additional validation here...
#endregion Pre-Conditions
this.something = something;
}
I hope this helps.
I would recommend applying the Single Responsibility Principle to the problem. It seems that the Action class should be responsible for one thing; executing the action. Given that, the validation should be moved to a separate object which is responsible only for validation. You could possibly use some generic interface such as this to define the validator:
IParameterValidator<TActionParameters>
{
Validate(TActionParameters parameters);
}
You can then add this to your base constructor, and call the validate method there:
protected BaseBusinessAction(IParameterValidator<TActionParameters> validator, TActionParameters actionParameters)
{
if (actionParameters == null)
throw new ArgumentNullException("actionParameters");
this.Parameters = actionParameters;
if (!validator.Validate(actionParameters))
throw new ArgumentException("Valid parameters must be supplied", "actionParameters");
}
There is a nice hidden benefit to this approach, which is it allows you to more easily re-use validation rules that are common across actions. If your using an IoC container, then you can also easily add binding conventions to automatically bind IParameterValidator implementations appropriately based on the type of TActionParameters
I had a very similar issue in the past and I ended up moving the logic to validate parameters to the appropriate ActionParameters class. This approach would work out of the box if your parameter classes are lined up with BusinessAction classes.
If this is not the case, it gets more painful. You have the following options (I would prefer the first one personally):
Wrap all the parameters in IValidatableParameters. The implementations will be lined up with business actions and will provide validation
Just suppress this warning
Move this check to parent classes, but then you end up with code duplication
Move this check to the method that actually uses the parameters (but then your code fails later)
Why not do something like this:
public abstract class BaseBusinessAction<TActionParameters>
: where TActionParameters : IActionParameters
{
protected abstract TActionParameters Parameters { get; }
protected abstract bool ParametersAreValid();
public void CommonMethod() { ... }
}
Now the concrete class has to worry about the parameters and ensuring their validity. I would just enforce the CommonMethod calling the ParametersAreValid method prior to doing anything else.
How about moving the validation to a more common location in the logic. Instead of running the validation in the constructor, run it on the first (and only the first) call to the method. That way, other developers could construct the object, then change or fix the parameters before executing the action.
You could do this by altering your getter/setter for the Parameters property, so anything that uses the paramters would validate them on the first use.
Where are the parameters anticipated to be used: from within CommonMethod? It is not clear why the parameters must be valid at the time of instantiation instead of at the time of use and thus you might choose to leave it up to the derived class to validate the parameters before use.
EDIT - Given what I know the problem seems to be one of special work needed on construction of the class. That, to me, speaks of a Factory class used to build instances of BaseBusinessAction wherein it would call the virtual Validate() on the instance it builds when it builds it.