2

私のプログラムは、Win32API 関数を介してオペレーティング システムと頻繁にやり取りします。今、私は自分のプログラムを Linux の Mono で実行するように移行したいと考えています (ワインなし)。これには、オペレーティング システムとの相互作用に異なる実装が必要です。

私は、プラットフォームごとに異なる実装を持つことができ、新しい将来のプラットフォーム用に拡張可能なコードの設計を開始しました。

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

この設計には 2 つの問題があります。

  1. の実装ISomeInterfacePlatformSpecificAttribute.
  2. 複数の実装を同じPlatformIDでマークできますが、メインでどれを使用すればよいかわかりません。最初のものを使用するのはうーん醜いです。

それらの問題を解決する方法は?別のデザインを提案できますか?

4

3 に答える 3

2

バンシーの情報源を見てください。プラットフォームに応じて、さまざまな実装を適切にプラグインする方法があります。

于 2010-05-21T13:42:05.807 に答える
0

Unity についておかしな話ですが、依存性注入コンテナーの使用を検討したことはありますか? Castle Windsor、StructureMap、および ninject はすべて Mono をある程度サポートしていると思います。

于 2010-05-19T12:03:05.470 に答える
0

2 つ以上の app.config ファイルを用意して、それぞれにプラットフォーム依存の実装を適宜挿入できると思います。

最後に、Windows では app.config の Windows バージョンが使用され、Unix では Unix バージョンが使用される場合は、重いタスクをプラットフォームに依存するインストールまたはその他の展開方法に任せます。

アドイン アーキテクチャまたはその他の複雑なソリューションを使用して、その他の優れた機能を実現できます。

于 2010-05-19T11:54:43.010 に答える