using System.Collections.Generic;
class DeviceContext : IDeviceContext
public void StartTexture()
Console.WriteLine("Starting texture on device context.");
Console.WriteLine("Ending texture on device context.");
public void Paint(string s)
Console.WriteLine("Drawing {0}", s);
abstract class RenderObject
public string Name { get; set; }
public List<RenderObject> Children { get; private set; }
protected readonly IDeviceContext _context;
public RenderObject(IDeviceContext context)
Children = new List<RenderObject>();
foreach (var o in Children) o.Render();
protected abstract void RenderInternal();
class ImageRenderObject : RenderObject
public string ImageFile { get; set; }
public ImageRenderObject(IDeviceContext context) : base(context) {}
protected override void RenderInternal()
Console.WriteLine("ImageRenderObject '{0}' is rendering an image of {1}", this.Name, this.ImageFile);
class TexturedRenderObject : RenderObject
public TexturedRenderObject(IDeviceContext context) : base(context) {}
protected override void RenderInternal ()
Console.WriteLine("TexturedRenderObject is rendering {0}", this.Name);
class CullingBird : ImageRenderObject
public CullingBird(IDeviceContext context) : base(context)
this.ImageFile = "CullingBird.png";
protected override void RenderInternal()
Console.WriteLine("ImageRenderObject '{0}' is rendering an image of {1}", this.Name, this.ImageFile);
class DivingWeasel : ImageRenderObject
public DivingWeasel(IDeviceContext context) : base(context)
this.ImageFile = "DivingWeasel.png";
class BarkingHorse : TexturedRenderObject
public BarkingHorse(IDeviceContext context) : base(context)
Children.Add(new CullingBird(context));
Children.Add(new DivingWeasel(context));
public void Render(RenderObject obj)
class RenderObjectFactory
protected readonly IDeviceContext _context;
public RenderObjectFactory(IDeviceContext context)
public T Create<T>(string name) where T : RenderObject
return Create<T>(name, Enumerable.Empty<RenderObject>());
public T Create<T>(string name, string imageFile) where T : ImageRenderObject
var instance = Create<T>(name, Enumerable.Empty<RenderObject>());
instance.ImageFile = imageFile;
public T Create<T>(string name, IEnumerable<RenderObject> children) where T : RenderObject
var instance = (T)Activator.CreateInstance(type, new[] {_context} );
instance.Children.AddRange(children);
public static void Main()
var factory = new RenderObjectFactory(new DeviceContext());
var divingWeasel = factory.Create<ImageRenderObject>("DivingWeasel", "DivingWeasel.png");
var cullingBird = factory.Create<ImageRenderObject>("CullingBird", "CullingBird.png");
var barkingHorse = factory.Create<TexturedRenderObject>("BarkingHorse", new RenderObject[] {divingWeasel, cullingBird} );
var almighty = new Almighty();
almighty.Render(barkingHorse);