//Rozdział 8.
//Most

//Konwencjonalny Most

public interface IRenderer
{
void RenderCircle(float radius);
    // RenderSquare, RenderTriangle etc.
}
 public abstract class Shape
{
    protected IRenderer renderer;
    //most między rysowaną figurą a
    //komponentem, który go rysuje
    public Shape(IRenderer renderer)
    {
        this.renderer = renderer;
    }
    public abstract void Draw();
    public abstract void Resize(float factor);
}

public class Circle: Shape
{
    private float radius;
    public Circle(IRenderer renderer, float radius) : base(renderer)
    {
        this.radius = radius;
    }
    public override void Draw()
    {
        renderer.RenderCircle(radius);
    }
    public override void Resize(float factor)
    {
        radius *= factor;
    }
}

public class VectorRenderer : IRenderer
{
    public void RenderCircle(float radius)
    {
        WriteLine($"Rysowanie okręgu o promieniu {radius}");
    }
}

var raster = new RasterRenderer();
var vector = new VectorRenderer();
var circle = new Circle(vector, 5);
circle.Draw(); //Rysowanie okręgu o promieniu 5
circle.Resize(2);
circle.Draw(); //Rysowanie okręgu o promieniu 10
var cb = new ContainerBuilder();
cb.RegisterType<VectorRenderer>().As<IRenderer>();
cb.Register((c, p) => new Circle(c.Resolve<IRenderer>(),
    p.Positional<float>(0)));

using (var c = cb.Build())
{
    var circle = c.Resolve<Circle>(
        new PositionalParameter(0, 5.0f)
    );
    circle.Draw();
    circle.Resize(2);
    circle.Draw();
}

// Most do dynamicznego prototypowania

// Log.cs
public class Log
{
    void Info(string msg) { ... }
}

// Payroll.cs
public class Payroll
{
    [Service]
    public Log Log { get; set; }
}
// ILog.cs
public interface ILog
{
    void Info(string msg);
}
// Log.cs
public class Log : ILog { /* jak wcześniej */ }

// Payroll.cs
public class Payroll
{
    [Service]
    public ILog Log { get; set; }
}
 
