您如何建议解决制作功能等效的Silverlight版本的代码的问题?我们希望尽可能重用代码,因为我们想继续开发代码的两个版本。
也许您可以推荐一些文章/书籍?
更新:该代码是一个非可视化组件。不是应用程序。没有第三方依赖项。
System.Drawing
,我猜测这个组件的功能与内存中的图像操作有关。如果是这种情况,考虑到移植所有代码的成本非常高,如果可能的话,可以考虑更改架构。把旧代码放在服务器端,在那里你可以自由地使用这些API,并通过一些Web服务向您的Silverlight应用程序公开所需的功能。如果组件没有GUI,那么这应该非常可行。根据您现有的代码架构,可能不太可能实现,但是您可以在WPF中加载Forms控件,请参阅这个示例。如果您的遗留代码打包成控件,则可以大量重用代码。希望这能帮到您。
using namespace-name
指令。使用条件编译来排除不支持的命名空间,例如:#if !SILVERLIGHT using System.Drawing; #endif
如果您正在使用 Silverlight 中缺少的枚举(例如 System.Drawing.Imaging.ImageFormat
),则引入等效的自定义枚举(例如 MyImageFormat
),并更改内部代码以仅使用自定义枚举。如有需要,添加使用自定义枚举(或等效的 Silverlight 枚举)的重载方法到公共接口。
对于结构体(例如 System.Drawing.PointF
),同样进行操作,或者更改代码以使用更简单的类型(例如两个 float
而不是 PointF
结构)。
使用条件编译排除使用不受支持的结构体的公共和私有代码。考虑重写内部代码,使其仅使用 .NET 和 Silverlight 支持的语言结构。
为访问 Silverlight 版本中的嵌入资源创建包装类,因为没有现成的包装类可以为二进制和文本资源提供 byte[]
或 string
。
创建一个像这样的属性
public static Encoding DefaultEncoding { get { #if SILVERLIGHT return Encoding.UTF8; #else return Encoding.Default; #endif } }
在您的代码中使用此属性,而不是Encoding.Default
。
迟早您将能够创建 Silverlight 版本的代码。这个版本可能会有较少的功能,但是,嘿,Silverlight 不是一个完整的 .NET。一些功能在 Silverlight 中甚至是不必要的。对于一些原始功能,您可能稍后添加等效的功能。
如果您正在使用 nunit 对您的 .NET 版本进行单元测试,那么您可能需要查看 nunit-silverlight(也请检查this page)。不过,有一些注意事项。
TestCaseSource
属性不受 nunit-silverlight 支持。如果您需要在测试中读取或写入本地文件,则应使用Silverlight 4作为测试应用程序。在Silverlight 3中无法实现此功能。您还应将测试应用程序设置为Out-of-Browser,并赋予其提升的信任权限(在Out-of-Browser设置中检查“要求提升的信任”)。
您需要一个包装器(是的,又一个)来读取和写入本地文件,因为Silverlight测试只能消耗和生成字节缓冲区和流。
以下是一些可能对包装器有用的代码片段:
获取当前文件夹的路径:
Uri uri = new Uri(System.Windows.Application.Current.Host.Source, relativeFileName);
var currentPath = uri.OriginalString;
currentPath
的开头删除file://
。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();
}
}
编写本地文件(还可以通过 COM 自动化)
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);
}
}
你可能还想检查一下Silverlight COM Toolkit。不过我自己没用过。
祝好运!
这里有另一个疯狂的想法。
将所有的 System.Drawing
、PInvoke、GDI 等内容隔离到一个单独的组件中,并将其封装为 ActiveX 对象。
将 ActiveX 对象嵌入到您的网页中,并让您的 Silverlight 应用程序以某种方式使用其服务。我猜这需要在网页层面上进行一些“管道”操作(例如,通过文档或其他方式激活 ActiveX 对象,并将结果暴露给 Silverlight 应用程序)。
这只是我最初的想法。我想它可以在很多方面得到改进。你觉得呢?:)
编辑:如果您的 Silverlight 代码可以在 Out-of-Browser 模式下运行,则 Silverlight 4 支持在 Silverlight 应用程序中嵌入 ActiveX 控件。这可能使将所有旧实现封装在某个 ActiveX 中并从 Silverlight 中使用成为可能。