Unity in C# for Platform Specific Implementations

Posted by DxCK on Stack Overflow See other posts from Stack Overflow or by DxCK
Published on 2010-05-19T11:48:51Z Indexed on 2010/05/19 11:50 UTC
Read the original article Hit count: 258

Filed under:
|
|
|
|

My program has heavy interaction with the operating system through Win32API functions. now i want to migrate my program to run under Mono under Linux (No wine), and this requires different implementations to the interaction with the operating system.

I started designing a code that can have different implementation for difference platform and is extensible for new future platforms.

public interface ISomeInterface
{
    void SomePlatformSpecificOperation();
}

[PlatformSpecific(PlatformID.Unix)]
public class SomeImplementation : ISomeInterface
{
    #region ISomeInterface Members

    public void SomePlatformSpecificOperation()
    {
        Console.WriteLine("From SomeImplementation");
    }

    #endregion
}

public class PlatformSpecificAttribute : Attribute
{
    private PlatformID _platform;

    public PlatformSpecificAttribute(PlatformID platform)
    {
        _platform = platform;
    }

    public PlatformID Platform
    {
        get { return _platform; }
    }
}

public static class PlatformSpecificUtils
{
    public static IEnumerable<Type> GetImplementationTypes<T>()
    {
        foreach (Assembly assembly in AppDomain.CurrentDomain.GetAssemblies())
        {
            foreach (Type type in assembly.GetTypes())
            {
                if (typeof(T).IsAssignableFrom(type) && type != typeof(T) && IsPlatformMatch(type))
                {
                    yield return type;
                }
            }
        }
    }

    private static bool IsPlatformMatch(Type type)
    {
        return GetPlatforms(type).Any(platform => platform == Environment.OSVersion.Platform);
    }

    private static IEnumerable<PlatformID> GetPlatforms(Type type)
    {
        return type.GetCustomAttributes(typeof(PlatformSpecificAttribute), false)
            .Select(obj => ((PlatformSpecificAttribute)obj).Platform);
    }
}

class Program
{
    static void Main(string[] args)
    {
        Type first = PlatformSpecificUtils.GetImplementationTypes<ISomeInterface>().FirstOrDefault();
    }
}

I see two problems with this design:

  1. I can't force the implementations of ISomeInterface to have a PlatformSpecificAttribute.
  2. Multiple implementations can be marked with the same PlatformID, and i dont know witch to use in the Main. Using the first one is ummm ugly.

How to solve those problems? Can you suggest another design?

© Stack Overflow or respective owner

Related posts about .NET

Related posts about c#