简体   繁体   English

如何创建可以使用两个名称空间之一的类?

[英]How to create a class that may use one of two namespaces?

I have a project which contains a class that draws on a graph. 我有一个项目,其中包含一个在图形上绘制的类。 The class looks like this:- 该类看起来像这样:

using System.Web.UI.DataVisualization.Charting;

namespace MyNameSpace
{
    public static class Utilities
    {
        public static void DrawOnGraph (Chart ourChart,
                                        // ...more parameters...
                                        )
        {
            ChartArea our_area = new ChartArea("Main");
            // Draw things
        }
    }
}

This is driven by a web application contained in another project in the same solution. 这由相同解决方案中另一个项目中包含的Web应用程序驱动。 I now have a requirement to create a forms application which will draw precisely the same graph using precisely the same inputs on to a web form. 现在,我需要创建一个表单应用程序,该应用程序将使用完全相同的输入在Web表单上绘制完全相同的图形。 I wish include the project into a second solution. 我希望将该项目纳入第二个解决方案。 But the class needs to look like this:- 但是该类需要看起来像这样:

using System.Windows.Forms.DataVisualization.Charting;

namespace MyNameSpace
{
    public static class Utilities
    {
        public static void DrawOnGraph (Chart ourChart,
                                        // ...more parameters...
                                        )
        {
            ChartArea our_area = new ChartArea("Main");
            // Draw things
        }
    }
}

I would like to know if it would be possible to use the same project/class/code for both, as naturally I don't want to cut'n'paste the code into two different places, and the only difference is the using directive. 我想知道是否可以对两者使用相同的项目/类/代码,因为自然地我不想将代码粘贴到两个不同的位置,唯一的区别是using指令。

I don't see how I can use generics as there are declarations inside the function of objects in the (alternative) namespaces, such as the ChartArea shown above. 我看不到如何使用泛型,因为(替代)名称空间中的对象的功能内部有声明,例如上面显示的ChartArea。 I can't see a way to use conditional compilation as which line is required depends on which solution the project is in, not the project itself, and it can't refer to the caller project as that would create a circular reference. 我看不到使用条件编译的方法,因为所需的行取决于项目所在的解决方案,而不是项目本身,并且不能引用调用方项目,因为这会创建循环引用。 Neither can I cast a web graph to a windows graph. 我也无法将网络图转换为Windows图。

The best I have been able to manage is to supply both using directives but comment one of them out according to which solution I am currently working on. 我能够管理的最好的方法是同时using指令来提供这两种指令,但要根据我当前正在使用的解决方案注释掉其中之一。 But that doesn't seem very satisfactory to me. 但这对我来说并不十分令人满意。 Is there a better way? 有没有更好的办法? Or should I not be so idle and write the code twice? 还是我不应该那么闲着写两次代码?

You can create your own abstraction on top of drawing logic and use wrapper pattern to encapsulate both charts. 您可以在绘图逻辑之上创建自己的抽象,并使用包装模式封装两个图表。 Then you would code against your abstraction and provide implementation form each forms and web project. 然后,您将针对抽象进行编码,并为每个表单和Web项目提供实现形式。 I assume the drawing graph logic in complicated enough to justify this approach. 我认为绘图逻辑很复杂,无法证明这种方法的合理性。 If you implement this it will allow you to introduce changes in graph in one place and it will affect both applications. 如果实施此方法,它将允许您在一处引入图形更改,这将影响两个应用程序。

The best soultion I can think of is to create wrapper-interfaces for classes, that both System.Web.UI.DataVisualization.Charting and System.Windows.Forms.DataVisualization.Charting provide/require. 我能想到的最好的办法就是为类创建包装器接口, System.Web.UI.DataVisualization.ChartingSystem.Windows.Forms.DataVisualization.Charting提供/要求。 Then provide two implementations of the interface: one for Forms and one for UI. 然后提供该接口的两种实现:一种用于Forms,一种用于UI。 Having that, your Utilities can call interface methods without knowing the exact implementation, and share code for both UI and Forms. 有了它,您的Utilities可以在不知道确切实现的情况下调用接口方法,并共享UI和Forms的代码。

One is for Web 一种是用于网络

using System.Web.UI.DataVisualization.Charting;

and the other one for windows 另一个用于Windows

using System.Windows.Forms.DataVisualization.Charting;

the issue is that they will be using classes that are relevant for their platform so I don think you able to achieve it 问题是他们将使用与其平台相关的类,所以我认为您无法实现

My advice would be to separate out the common functionality in to a library which is not dependant for Web or Windows and use this in to two different solution one for web and the other for windows, this way alteast you have reduced the code repetition twice 我的建议是将通用功能分离到不依赖于Web或Windows的库中,并将其用于两个不同的解决方案,一个用于Web,另一个用于Windows,这样至少可以减少两次代码重复

Update : 更新:

Another option is to write it as Windows Control library and then make it available in the web application as a DLL. 另一种选择是将其编写为Windows Control库,然后以DLL的形式在Web应用程序中使用。 Please look at this example http://www.beansoftware.com/ASP.NET-Tutorials/Place-Windows-Control-To-Web-Form.aspx 请查看此示例http://www.beansoftware.com/ASP.NET-Tutorials/Place-Windows-Control-To-Web-Form.aspx

You can use conditional compilation if your code calls the 'identical' parts of the respective APIs of Web.UI and Windows.Forms Charting, that include operations with Series, ChartArea, etc. 如果您的代码调用了Web.UI和Windows.Forms Charting的相应API的“相同”部分,则可以使用条件编译 ,其中包括对Series,ChartArea等的操作。

Simply compile the code twice: once using Web.UI Charting and the other using Windows.Forms Charting. 只需将代码编译两次:一次使用 Web.UI图表,而另一个使用 Windows.Forms图表。 Use conditional compilation to enable/disable assembly references so one assembly targets applications based on WinForms and the other WebUI Charting apps. 使用条件编译来启用/禁用程序集引用,以便一个程序集基于WinForms和其他WebUI Charting应用程序定位应用程序。

Alternatively, in some quick-and-dirty situations you could get by with just the Windows.Forms Charting API, and whenever html is needed, eg a src attribute for an img element, merely use Chart.SaveImage (..), and so on. 另外,在一些肮脏的情况下,您可以仅使用Windows.Forms Charting API,并且每当需要html时,例如img元素的src属性,只需使用Chart.SaveImage (..),等等。上。 But this has drawbacks. 但这有缺点。

Both of these alternatives are limiting because the respective APIs and functionalities of Web.UI and Windows.Forms Charting don't overlap enough. 这两种选择都是有局限性的,因为Web.UI和Windows.Forms Charting各自的API和功能重叠不够。 And SaveImage() is additionally limiting because you don't want your web app burdened by the Windows.Forms assemblies and extraneous operations. 而且SaveImage()还有其他限制,因为您不想让Windows.Forms程序集和无关的操作负担您的Web应用程序。

Nonetheless the conditional compilation approach will work even if the web and forms assemblies diverge. 尽管如此,即使Web和表单程序集有所不同,条件编译方法仍将有效。 You will be able to maintain shared codes (but conditionally compiled for web or forms), but each library will accumulate new code specific to its web or forms target. 您将能够维护共享代码(但有条件地针对Web或表单进行编译),但是每个库都将积累特定于其Web或Forms目标的新代码。 This approach works best with a good approach to build configuration. 此方法与构建配置的良好方法一起使用效果最佳。 If you have a good approach to build configuration I think it will be easier to maintain and extend than other approaches. 如果您拥有构建配置的好方法,我认为它将比其他方法更易于维护和扩展。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM