【问题标题】:Unity in C# for Platform Specific Implementations用于平台特定实现的 C# 中的 Unity
【发布时间】:2010-05-19 11:48:51
【问题描述】:

我的程序通过 Win32API 函数与操作系统进行大量交互。现在我想将我的程序迁移到Linux下的Mono下运行(没有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中使用哪个。使用第一个是 ummm 丑陋的。

如何解决这些问题?你能推荐另一种设计吗?

【问题讨论】:

    标签: c# .net mono multiplatform


    【解决方案1】:

    查看 Banshee 的来源。他们有一种巧妙的方式来根据平台插入不同的实现。

    【讨论】:

      【解决方案2】:

      我认为您可以准备两个或多个 app.config 文件,然后在每个文件中相应地注入平台相关的实现。

      最后,将繁重的任务留给平台相关的安装或任何其他部署方法,在 Windows 上使用 app.config 的 Windows 版本,而在 Unix 上使用 Unix 版本。

      您可以使用插件架构或其他复杂的解决方案来实现其他不错的功能。

      【讨论】:

        【解决方案3】:

        你提到 Unity 很有趣,你考虑过使用依赖注入容器吗?我相信 Castle Windsor、StructureMap 和 ninject 都可能在一定程度上支持 Mono。

        【讨论】:

        • 你不在这里。几乎所有流行的 DI 容器都未能通过 MoMA 测试。 Unity 没有通过所有 MoMA 测试,但在某些情况下它在 Mono 上运行良好。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-11-09
        • 1970-01-01
        • 2020-06-04
        • 2018-06-24
        • 1970-01-01
        • 2023-03-07
        相关资源
        最近更新 更多