2010-05-19 26 views
0

我的程序通過Win32API函數與操作系統有很大的交互。現在我想將我的程序遷移到Linux下的Mono下運行(無酒),這需要與操作系統進行交互的不同實現。C#中針對平臺特定實現的統一

我開始設計一個代碼,可以針對不同的平臺實現不同的實現,並且可以爲新的未來平臺擴展。

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中使用哪個。使用第一個是醜陋的。

如何解決這些問題?你能提出另一種設計嗎?

回答

0

我想你可以準備兩個或兩個以上的app.config文件,然後在每個相應的注入依賴於平臺的實現。

最後,留下沉重的任務依賴於平臺的安裝或任何其它的部署方法,當在Windows上使用的app.config的Windows版本,而在Unix上使用Unix版本。

您可以使用插件體系結構或其他複雜的解決方案,以達到很好的特性。

0

有趣的你提到統一,你有沒有考慮過使用依賴注入容器?我相信Castle Windsor,StructureMap和ninject都可能有一定程度的單聲道支持。

+0

你不是在這裏。幾乎所有流行的DI容器都未通過MoMA測試。 Unity沒有通過所有的MoMA測試,但在某些情況下,它在Mono上運行良好。 – 2010-05-22 02:32:26

2

看看Banshee的來源。他們有一種整潔的方式來根據平臺插入不同的實現。