问题本身在这里很简单,但所有解决方案似乎都很糟糕,所以我无法决定哪个是最好的,所以我想在这里问一下......
我目前包装了一些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);
}
// ...
}
所以真的没有自定义逻辑,它只是一个愚蠢的包装。