I want my C# engine to give the user the choice between using Direct3D or OpenGL. My engine internally is designed like this abstracted example for a shader class:
internal class Shader
{
private IShaderImplementation _implementation;
internal Shader(ShaderType type, string code)
{
switch (Engine.GraphicsInterface)
{
case GraphicsInterface.Direct3D:
_implementation = new Direct3DShader(type, code);
break;
case GraphicsInterface.OpenGL:
_implementation = new OpenGLShader(type, code);
break;
default:
throw new UnsupportedInterfaceException("Shader");
break;
}
}
internal void Compile()
{
_implementation.Compile();
}
}
I thought this is a good design pattern. (I also prefer calling constructors over factory methods as you might have noticed, but that's just a side thing).
However:
- I don't want to stuff OpenTK (for OpenGL stuff) assembly references together with SharpDX (for Direct3D stuff) assembly references in one class library. I don't even know if that is a good idea. From the current design this would be required as the Direct3DShader and OpenGLShader classes reference D3D or OGL methods directly. Wouldn't I need to ship out both OpenTK / SharpDX assemblies even if the user only wishes to use OpenGL for example?
- I'd prefer to have one main assembly containing only the general interface stuff as seen above (let's say "Awful.Engine.dll", and another one for only OpenGL stuff ("Awful.Engine.OpenGL.dll"), another one for Direct3D stuff ("Awful.Engine.Direct3D"). But how can this be referenced in the main assembly? As you can see I have an enumeration of interfaces, this wouldn't work anymore.
Asking in a more general form, how can my main assembly interfaces and classes get implemented and extended in sub assemblies?
PS: I've heard about reflection about which I know a cent or two, and then the managed extensibility framework, but I have not figured out how it can fit into my design.