如何使现有C#代码的Silverlight版本依赖于System.Drawing命名空间

如何使现有C#代码的Silverlight版本依赖于System.Drawing命名空间,c#,silverlight,porting,system.drawing,C#,Silverlight,Porting,System.drawing,我们有相当多的C#2.0代码严重依赖System.Drawing命名空间。还有一些WinGDI依赖项(通过互操作) 您建议如何解决在功能上等同于Silverlight版本的代码的问题?我们希望尽可能地重用代码,因为我们希望继续开发代码的两个版本 也许你可以推荐一些文章/书籍 更新:代码是非可视组件。不是申请。不存在第三方依赖关系。这几乎是不可能的,因为WPF和Silverlight都与此的旧版本有根本的不同。如果您真的希望能够同时开发桌面和web应用程序,那么最好使用WPF和Silverligh

我们有相当多的C#2.0代码严重依赖System.Drawing命名空间。还有一些WinGDI依赖项(通过互操作)

您建议如何解决在功能上等同于Silverlight版本的代码的问题?我们希望尽可能地重用代码,因为我们希望继续开发代码的两个版本

也许你可以推荐一些文章/书籍


更新:代码是非可视组件。不是申请。不存在第三方依赖关系。

这几乎是不可能的,因为WPF和Silverlight都与此的旧版本有根本的不同。如果您真的希望能够同时开发桌面和web应用程序,那么最好使用WPF和Silverlight

唯一的问题是重用代码仍然很困难,因为Silverlight没有WPF所具有的所有特性。除此之外,Silverlight中访问数据的模型是完全异步的

最好在Silverlight中构建应用程序,然后将该应用程序移植到WPF


可能不是您想要的答案。

我在创建以前使用winforms构建的wpf/silverlight版本软件方面有丰富的经验。很遗憾,但在你的情况下,当你使用大量的互操作和系统绘图时,几乎不可能做到这一点

当然,您总是可以尝试(实际上您总是必须)将业务逻辑与接口分离,但在这种情况下(我希望是错误的!),您的接口必须完全重新设计,因为winforms和wpf/silverlight的架构不同

根据我的经验,这个问题是这样解决的:所有旧的winforms组件都保持不变,但所有新功能都是在将wpf控件注入winforms应用程序的帮助下使用wpf构建的


是的,有时候这很奇怪,但它确实比浪费所有旧代码并在新代码上花费大量时间和金钱更有效率,这也是一样的

根据现有代码库的架构,这可能是不可能的,但您可以在WPF内部加载表单控件,请参阅。如果您的遗留代码被打包到控件中,那么您可能能够获得大量代码重用。我希望这会有所帮助。

如果没有GUI,而您仍在使用大量的
系统。绘制
我猜此组件的功能与内存中图像的管理有关

如果是这样的话,由于移植所有代码的成本很高,如果可能的话,你可以考虑改变你的体系结构。 将旧代码放在服务器端,在那里您可以自由使用这些API,并通过一些web服务向Silverlight应用程序公开所需的功能。如果组件没有GUI,那么它应该是非常可行的

编辑:添加建议,说明这可能适合开发人员

也许这仍然有效-如果您的开发人员计划在网页中部署此Silverlight控件,那么他可能有一个web服务器,可以将您的组件放置在该服务器上,以便Silverlight代码可以访问

如果开发人员计划在非浏览器模式下部署Silverlight代码,则可以制作嵌入旧组件的版本(例如作为COM对象)


除上述方法外,另一种方法是将此组件自己托管在服务器上,或在某些公共云(如Windows Azure)上。

这里是另一个疯狂的想法

将所有
系统.绘图
、PInvoke、GDI等隔离到单独的组件中,并将其包装为ActiveX对象

在网页中嵌入ActiveX对象,并使Silverlight应用程序以某种方式使用其服务。我想这需要在网页级别上进行一些“管道”操作(例如,一个脚本可以激活ActiveX对象,并通过文档或其他方式将结果公开给Silverlight应用程序)

这只是我最初的想法。我想它可以在很多方面得到改进。你觉得怎么样?:)


编辑:如果可以接受Silverlight代码在浏览器模式之外运行,则Silverlight 4支持在Silverlight应用程序中嵌入ActiveX控件。这可能使您可以将所有旧实现封装在某个ActiveX中,并从Silverlight使用它。

首先,您应该接受原始代码的一些功能将无法应用到Silverlight版本。互操作、读取和写入文件-由于安全原因,这些内容被禁止,或者只是不受支持

要记住的第二件事是,您的代码将被条件编译所污染(如果您希望继续支持从相同的代码库构建.NET版本)

第三件事是——您必须编写一些新代码(而不是删除的代码)。例如,您可能需要创建接受
WriteableBitmap
的新方法,而不是接受
System.Drawing.Bitmap
的方法,以便为Silverlight版本的用户提供类似的功能集

OK,让我们来看看为了创建Silverlight版本的.NET库,您可能需要做些什么。

  • 为Silverlight版本创建新项目
  • 将所有现有代码文件作为链接添加到此项目
  • 尝试构建项目。构建很可能会失败,并显示许多警告和错误消息。显然,我们的目标是解决所有这些问题 下面是一些关于如何修复常见构建错误的提示

  • 使用命名空间名称删除所有不需要的
    指令。使用条件编译排除不支持的命名空间,如下所示:
  • 和你 #if !SILVERLIGHT using System.Drawing; #endif public static Encoding DefaultEncoding { get { #if SILVERLIGHT return Encoding.UTF8; #else return Encoding.Default; #endif } }
    Uri uri = new Uri(System.Windows.Application.Current.Host.Source, relativeFileName);
    var currentPath = uri.OriginalString;
    
    private static byte[] readBinaryFile(string fileName)
    {
        const int adTypeBinary = 1;
    
        using (dynamic adoCom = System.Runtime.InteropServices.Automation.AutomationFactory.CreateObject(@"ADODB.Stream"))
        {
            adoCom.Type = adTypeBinary;
            adoCom.Open();
            adoCom.LoadFromFile(fileName);
    
            return adoCom.Read();
        }
    }
    
    private static void writeBinaryFile(string fileName, byte[] binaryArray)
    {
        const int adTypeBinary = 1;
        const int adSaveCreateOverWrite = 2;
        using (dynamic adoCom = System.Runtime.InteropServices.Automation.AutomationFactory.CreateObject(@"ADODB.Stream"))
        {
            adoCom.Type = adTypeBinary;
            adoCom.Open();
            adoCom.Write(binaryArray);
            adoCom.SaveToFile(fileName, adSaveCreateOverWrite);
        }
    }