Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Identify implementations of base class in an array

I have the following problem: I have a set of engines which automaticly (listening to events) controls my model. The following picture shows in general the class diagram: Class Diagramm

Now I have a client which knows the EngineFacade and i want to set the property Active from Engine2 from the client, but neither the client nor the EngineFacade knows which of the three engines is Engine2.

There are two ways, but I dont like any of them:

  1. Check if one of the engines is of type Engine2 - if there is another class which does the same task but is named different I have to change it in the EngineBuilder AND in the EngineFacade.
  2. Check with an identifier string - I dont really like magic strings.

What I know on the client site is that there is or should be an engine which handels the grid. But I dont know more.

Maybe I have to choose between the two devils, but maybe one of you has a better solution.

like image 735
Yggdrasil Avatar asked Mar 07 '13 14:03

Yggdrasil


1 Answers

You could use an attribute on the implementation of Engine2, like so:

[AttributeUsage(AttributeTargets.Class)]
public class HandlesGridAttribute : Attribute { }

Which you then apply to your derivation:

[HandlesGrid]
public Engine2 : EngineBase { ... }

Then, in your client, check for the attribute:

IEnumerable<EngineBase> bases = ...;

// Get all the implementations which handle the grid.
IEnumerable<EngineBase> handlesGrid = bases.
    Where(b => b.GetType().
        GetCustomAttributes(typeof(HandlesGridAttribute), true).Any());

// Set the active property.
foreach (EngineBase b in handlesGrid) b.Active = true;

The major drawback here (which may or may not apply to you) is that you can't change the value at runtime (since the attribute is baked in at compile time). If your engine is not dynamic in this way, then the attribute is the right way to go.

If you need to change whether or not a derivation can perform this action at runtime though, then you have to fall back to your second option, code constructs that identify what the attributes of the engine are. Mind you, it doesn't have to be a string (and I don't like that either), but it can be something that is more structured that will give you the information you're looking for.

like image 125
casperOne Avatar answered Oct 12 '22 10:10

casperOne