It may be sufficient to create a method that will serve to visit any object that implements an interface, rather than the final concrete type. In this way, a single abstract method would be responsible for visiting various types of concrete objects that implement that interface, including objects imported via plug-in.
In this way it is possible to add more types dynamically, however it would limit the work of the method, which would work on the interface and not on the concrete type ... this limitation can be bypassed by interfacing with a Accept
method that takes a object visitor, and is able to pass sub-objects to the visitor.
C # example:
class Concrete
{
}
/// <summary>
/// Interface de plug-in que pode ser visitada por um Visitor.
/// </summary>
interface IPlugin
{
void Accept(Visitor visitor);
}
class Plugin1 : IPlugin
{
public Concrete Concrete { get; set; }
public void Accept(Visitor visitor)
{
visitor.Visit(this.Concrete);
}
}
abstract class Visitor
{
public void Visit(object obj)
{
if (obj is Concrete)
this.Visit(obj as Concrete);
else if (obj is IPlugin)
this.Visit(obj as IPlugin);
}
public abstract void Visit(Concrete concrete);
public virtual void Visit(IPlugin plugin)
{
plugin.Accept(this);
}
}