I am working on a game project using Microsoft XNA framework, although this question is a generic one that involves decoupling of classes/systems.
Let's say i have a class (simplified to suit this example) as shown here:
public class GameCell
{
public Color Color { get; set; }
}
I would like to reuse as much code as i can between multiple platforms that use C#.
The problem of directly referncing the Color struct is that this type is defined in the XNA assemblies, creating a strong coupling (or dependency) between my code and XNA.
The other framework i will be using may (or may not) have its own Color object, with its own set of properties and API.
I would like to have the same source file "know" to use either the XNA or other framework's implementation automagically.
I know other types of decoupling methods such as IoC, but that would mean i would be plugging in different versions of a system/class, instead of reusing the same class in different contexts.
Is this even possible to do? how would u suggest to keep such a system portable?
I've seen some cases (in native C++ development) where you would define a set of classes that mirror the classes the framework you're using has (for example here - define Color again), and so it is possible to "re-map" this later on to use different classes, upon need.
Another option is to mess around using #IFDEF to play with the using statements in the header of the class (switching from XNA to other platforms). What is the best alternative in this case?
Typically what you do is create your own Color
structure and have it do the translation using conditional compilation switches. For example:
#define USE_DOTNET
//#define USE_SOMETHINGELSE
#if USE_DOTNET
using System.Drawing;
#endif
#if USE_SOMETHINGELSE
using SomethingElse.Drawing;
#endif
public struct MyColor
{
#if USE_DOTNET
Color TheColor;
#endif
#if USE_SOMETHINGELSE
SomethingsColor TheColor;
#endif
public int R
{
get
{
#if USE_DOTNET
// code to return .NET Color.R value
#endif
#if USE_SOMETHINGELSE
// code to return SomethingColor.R value
#endif
}
}
}
Another way is to have separate regions for the .NET and SomethingElse code. For example:
#if USE_DOTNET
public int R
{
get { return TheColor.R; }
}
// other properties and methods here
#endif
#if USE_SOMETHINGELSE
// properties and methods for using SomethingElse
#endif
This can work well, but you have to be very careful when writing your code so that you don't use the .NET Color
structure anywhere but in these portability layers.
We used this technique in C/C++ when developing games that had to run on Windows, the Mac, and several different game consoles. It's a pain to set up the portability layers, but once they're set up, it's pretty easy to use.
I would caution you, though, not to give your portability classes and structures the same names as classes or structures from the .NET libraries or the other libraries you're using. If you do that, you're going to confuse yourself, and you're likely to write some non-portable code that you won't discover until you start trying to port it. (Not that I'm speaking from experience or anything . . .)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With