Unity в C # для платформо-специфичных реализаций - PullRequest
1 голос
/ 19 мая 2010

Моя программа интенсивно взаимодействует с операционной системой через функции Win32API. Теперь я хочу перенести мою программу для запуска под Mono под Linux (без Wine), и для этого требуются различные реализации для взаимодействия с операционной системой.

Я начал разрабатывать код, который может иметь различную реализацию для разных платформ и может быть расширен для новых будущих платформ.

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();
    }
}

Я вижу две проблемы с этим дизайном:

  1. Я не могу заставить реализации ISomeInterface иметь PlatformSpecificAttribute.
  2. Несколько реализаций могут быть помечены одинаковыми PlatformID, и я не знаю, какие из них использовать в Main. Использование первого - ужасно.

Как решить эти проблемы? Можете ли вы предложить другой дизайн?

Ответы [ 3 ]

2 голосов
/ 21 мая 2010

Посмотрите на источник для Банши. Они имеют удобный способ подключения различных реализаций в зависимости от платформы.

0 голосов
/ 19 мая 2010

Забавно, что вы упомянули Unity, вы рассматривали возможность использования контейнера для инъекций зависимости? Я считаю, что Castle Windsor, StructureMap и ninject могут иметь некоторую степень поддержки Mono.

0 голосов
/ 19 мая 2010

Я думаю, что вы можете подготовить два или более файла app.config, а затем внедрить зависимую от платформы реализацию соответственно в каждом.

Наконец, оставьте тяжелую задачу для зависимой от платформы установки или любых других методов развертывания, если в Windows используется версия app.config для Windows, а в Unix используется версия Unix.

Вы можете использовать архитектуру надстроек или другие сложные решения для достижения других полезных функций.

...