私のプログラムは、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 つの問題があります。
- の実装
ISomeInterface
にPlatformSpecificAttribute
. - 複数の実装を同じ
PlatformID
でマークできますが、メインでどれを使用すればよいかわかりません。最初のものを使用するのはうーん醜いです。
それらの問題を解決する方法は?別のデザインを提案できますか?