技术开发 频道

Mono在Linux上的开发与实践札记

  【IT168 技术】最近有个政府项目,客户指定服务器程序必须跑在Linux上面,于是乎我们这帮Linux菜鸟立马开装Linux系统并部署Mono环境。因为对Linux实在不熟的缘故,故在RedHat Enterprise Linux 6中始终没有将MonoDevelop跑起来,于是团队中有同事提议“干脆转Java平台算哒”,哎呦,这么“反动”的想法必须得镇压在萌芽状态。好吧,我承认有些许的个人主观因素作祟,但终究还是需要些冠冕堂皇理由的:

  因为公司现有所有产品都是基于.NET平台,绝大数开发人员也只有.NET开发经验,这样的平台迁移是个非常大成本的事件,而且涉及公司的整个软件开发的方向性转移,绝不可贸然行事。

  我一直主张将所有产品统一开发平台,最终将各条产品线全部基于自己研发的插件框架,如果并行Java和.NET两个开发平台,其中涉及的开发量和代码移植、版本同步、双向兼容……想想就是一个浩大而繁琐的工程,这样的焦油坑一定要避免陷入进去。

  目前的问题其实只是团队对Mono on Linux的经验匮乏,这个问题还不至于严重到需要迁移开发平台,起码我们还有Mono这样一根救命稻草。所以,我们要做的只是尽快熟悉Linux和积累Mono on Linux上面的一些移植经验,当然,我知道把C#代码移植过去通过Mono的编译并不难,问题在于有些API的细节差异和某些代码契约需要通过一定时间的经验来规避某些小陷阱,但是,这些都是可以解决的。

  Mono现在最新稳定版本是2.10.2,对C# 4.0已经支持的很完整了。而且后面很快会有ASP.NET MVC3的完整实现,虽然没有看到对ADO.NET EntityFramework的支持计划,但是,我们曾经实现过以DataSet为数据载体的数据访问框架,所以完全可以借鉴ADO.NET EF的设计思想去实现一个适度ORM数据引擎,当然这个事情得推后一点才有精力去做,但是想想就是一件多么有趣的事情啊。

  上面晓之以理,下面就该动之以情了,你看这次的Android版的警务通就是用Java来搞的,没有使用那个MonoDroid吧,为啥?因为Mono for Android实在太不成熟了,用它写的程序的无论是体积还是运行效率都没法跟人家比,确实不在一个等级。总而言之,量体裁衣、具体对待。

  部门会餐后,俺决定从这个项目组开始逐步进行双机开发,每人配两台电脑,一台装Windows、一台装Linux,在Windows中用VS开发,调试通过后签入SVN中,再在Linux中签出使用MonoDevelop进行一遍单元测试,不用虚拟机,一切原生态同步开发,提升每个开发人员对Linux的熟悉和积累对Mono on Linux的开发经验,于公于私都是非常给力的!

  RHEL6中MonoDevelop装不上,咱没功夫跟它耗,赶紧上OpenSUSE和CentOS,这两个都是MonoDevelop官网的主荐平台,果然很给力相当的顺。下面是今天(2011-7-5)将一些后台代码移植到Mono on Linux中的实践札记:

  众所周知Linux的文件系统路径是区分大小写的,所以在代码中千万不能简单拼接文件路径,推荐使用 System.IO.Path 类中的相关方法进行路径操作,另外,对于文本中的分行要使用 Environment.NewLine属性,或者 AppendLine 之类的方法来处理以规避操作系统的差异。

  避免使用Win32 API的P/Invoke操作,这点好在Linux上只是跑服务器端代码,所以基本不会涉及。

  今天移植的两个类库时,只碰到下面两个问题花了一点时间,就运行测试通过了,好爽。

  一、在.NET 4.0的System.Type中新增了这个GetType(…)方法重载:

public static Type GetType(string typeName, Func<AssemblyName, Assembly>assemblyResolver, Func<Assembly, string, bool, Type> typeResolver, bool throwOnError)

  我的代码是这样使用的:

public static Type GetType(string typeFullName)
{
    
if(string.IsNullOrWhiteSpace(typeFullName))
        
return null;
    
return Type.GetType(typeFullName, assemblyName =>
     {
         Assembly assembly
= ResolveAssembly(assemblyName);
        
if(assembly == null)
             assembly
= LoadAssembly(assemblyName);
        
return assembly;
     },
null, false);
}
0
相关文章