包装底层对象时创建SpriteBatch的最佳方法

时间:2012-01-23 11:38:02

标签: c# dependency-injection xna wrapper factory-pattern

问题本身在这里很简单,但所有解决方案似乎都很糟糕,所以我无法决定哪个是最好的,所以我想在这里问一下......

我目前包装了一些XNA组件(SpriteBatch,GraphicsDevice,ContentLoader等),大多数情况下它们包装了所有内容1-1但是在可选参数减少函数重载方面存在一些差异。这主要是为了启用依赖注入并使我能够在测试中更容易模拟,因为我宁愿使用注入模式而不是服务定位器模式(尽管我还创建了一个实现IServiceProvider的NinjectServiceProvider)。 p>

无论如何,这里的主要问题是我需要新建几个不同的ISpriteBatch对象,因为不同的组件使用不同的混合模式等。所以我已经将SpriteBatchFactory对象改为新的。在我继续这里之前是一些示例片段,以便您可以看到我来自哪里:

public class MySpriteBatch : ISpriteBatch
{
    private SpriteBatch underlyingSpriteBatch;
    private IGraphicsDevice graphicsDevice;

    public MySpriteBatch(SpriteBatch underlyingSpriteBatch, 
        IGraphicsDevice graphicsDevice)
    { 
        this.underlyingSpriteBatch = underlyingSpriteBatch; 
        this.graphicsDevice = graphicsDevice;
    }

// ...
}

MyGraphicsDevice:

public class MyGraphicsDevice : IGraphicsDevice
{
    private GraphicsDevice underlyingGraphicsDevice;

    public MyGraphicsDevice(GraphicsDevice underlyingDevice)
    {
        this.underlyingGraphicsDevice = underlyingDevice;
    }

    // ...
}

SpriteBatchFactory:

public class SpriteBatchFactory
{
    public SpriteBatchFactory(IGraphicsDevice graphicsDevice)
    {
        this.GraphicsDevice = graphicsDevice;
    }

    public IGraphicsDevice GraphicsDevice { get; private set; }

    public ISpriteBatch Create()
    {
        var underlyingGraphicsDevice = ????

        var underlyingSpriteBatch =
            new SpriteBatch(underlyingGraphicsDevice);

        return new MySpriteBatch(underlyingSpriteBatch,
            this.GraphicsDevice);
    }
}

现在,你可以看到新的MySpriteBatch(ISpriteBatch),我需要一个新的SpriteBatch,这反过来需要一个GraphicsDevice实例......这是我不确定如何最好地满足这种依赖... ...我想到的几个解决方案是:

1)MyGraphicsDevice包含这个,但它没有公开,所以我可以将它作为接口级别的对象或具体类级别的实际GraphicsDevice公开。无论哪种方式,这将需要铸造它是对象 - > GraphicsDevice或IGraphicsDevice - > MyGraphicsDevice。

2)每次我需要新建MySpriteBatch时,我给SpriteBatchFactory一个GraphicsDevice而不是IGraphicsDevice和新的。

3)我在内部使MySpriteBatch成为一个SpriteBatch,并使其需要一个MyGraphicsDevice并在那里公开,所以MySpriteBatch对SpriteBatch没有外部依赖。

我认为第三个听起来更加封装的方式,但我不喜欢任何一种方式,所以其他人可以想出一个更好的解决方法吗?我不是因为我不想创建这个跨平台而烦恼,只是试图在Xna和我的框架之间给我一个更可控的层。

===编辑===

当我说我正在包装底层组件时,我的意思是字面上包含调用,即:

public class MyGraphicsDevice : IGraphicsDevice
{
    private GraphicsDevice underlyingGraphicsDevice;

    public MyGraphicsDevice(GraphicsDevice underlyingDevice)
    {
        this.underlyingGraphicsDevice = underlyingDevice;
    }

    public VertexBuffer[] GetVertexBuffers()
    {
        return underlyingGraphicsDevice.GetVertexBuffers();
    }

    public void SetRenderTarget(RenderTarget2D renderTarget)
    {
        underlyingGraphicsDevice.SetRenderTarget(renderTarget);
    }

    // ...
}

所以真的没有自定义逻辑,它只是一个愚蠢的包装。

0 个答案:

没有答案