[英]How to setup a solution which has projects for winforms and web?
In my solution I have a few projects: 在我的解决方案中,我有几个项目:
A key feature of the application is to dynamically generate controls. 该应用程序的关键功能是动态生成控件。 I have a class with an enum, and based on an enum value a particular control must be returned. 我有一个带有枚举的类,并且必须基于枚举值返回特定的控件。 So I've created a factory in the core project like this: 因此,我在核心项目中创建了一个工厂,如下所示:
public IControl Create(Enum enum)
{
switch(enum)
{
case "enum.A":
return new CheckBoxControl();
case "enum.B":
return new RadioControl();
}
}
Ass you might have guessed, I have custom controls. 您可能已经猜到的屁股,我有自定义控件。 They all inherit from an Interface (IControl). 它们都继承自接口(IControl)。 But in this case, CheckBoxControl and RadioControl are WinFroms controls. 但是在这种情况下,CheckBoxControl和RadioControl是WinFroms控件。
Now, these controls resides in the core project. 现在,这些控件位于核心项目中。 I don't want this, because it is a core library and I want this library to be platform independent. 我不想要这个,因为它是一个核心库,并且我希望这个库是平台无关的。
I want the winforms controls in a WinCore project and the WebControls in a WebCore project. 我想要WinCore项目中的Winforms控件和WebCore项目中的WebControl。 The problem is, How can I return the right controls from the core project? 问题是,如何从核心项目中返回正确的控件?
Both, the WebCore and WinCore project need a reference to the core project, because the core project contains my entities. WebCore和WinCore项目都需要对核心项目的引用,因为核心项目包含我的实体。 This means, that I can't set a reference from the core the web- or wincore project. 这意味着,我无法从Web或Wincore项目的核心设置引用。
How to solve this? 如何解决呢?
I would do that: 我会这样做:
.Core should be an assembly containing business . .Core 应该是包含业务的程序集 。
.Shared should be an assembly containing infraestructure, base classes and interfaces that are platform and technology-independent - so this will let you referene it in any project avoiding unwanted dependencies -. .shared 应该是一个程序集,其中包含与平台和技术无关的基础结构,基类和接口-因此,您可以在任何项目中引用它,避免不必要的依赖关系-。
.Web should be the assembly containing web-oriented functionality .Web 应该是包含面向Web的功能的程序集
.Web.Forms should be the assembly containing Web Forms and Web Controls only . .Web.Forms 应该是仅包含Web窗体和Web控件的程序集 。
.Windows should be the assembly contaning Windows-oriented functionality. .Windows 应该是组装contaning面向Windows的功能。
.Windows.Forms should be the assembly contaning Windows Forms and Controls only. .Windows.Forms 应该是仅包含Windows窗体和控件的程序集。
Having such assembly structure, IControl interface should be in .Shared assembly and this should be referenced by .Core , allowing code to add IControl instances without needing technology-specific dependencies. 具有这样的程序集结构,IControl接口应该在.Shared程序集中 ,并且应该由.Core引用,从而允许代码添加IControl实例而无需特定于技术的依赖关系。
In addition, this solution is enough to let .Windows , .Windows.Forms , .Web and .Web.Forms reference .Core and/or .Shared . 另外,此解决方案足以让.Windows , .Windows.Forms , .Web和.Web.Forms引用.Core和/或.Shared 。
UPDATE:
更新:
It's just a suggestion, but why are you using an enumeration in your factory?
这只是一个建议,但是为什么要在工厂中使用枚举?
You could do that:
您可以这样做:
public TControl Create<TControl>() where TControl : IControl, new() { IControl control = new TControl(); // Control initialization work return control; }
What do you think?
你怎么看?
Nevermind that, it was just a suggestion because maybe, with some refactoring, you could use this kind of factory method, but I can understand this is far from your current implementation. 没关系,这只是一个建议,因为也许通过某种重构,您可以使用这种工厂方法,但是我可以理解,这与您当前的实现相去甚远。 Concentrate better in my answer :) 在我的回答中集中精力更好:)
UPDATE 2: 更新2:
How inversion of control can help you in your problem? 控制反转如何帮助您解决问题?
In fact, if you register inversion of control components, you're going to access them by type or by some unique identifier. 实际上,如果注册了控件组件的反转,则将按类型或某些唯一的标识符访问它们。
Let's say you've the IControl
interface (the service) and WindowsTextBox and WebFormsTextBox both implementing IControl
. 假设您拥有IControl
接口(该服务)以及WindowsTextBox和WebFormsTextBox都实现了IControl
。 In your configuration file you're goint to have two components, which have both same service type (the interface) and two different implementations and these will be marked with two different identifiers: 在配置文件中,您将必须具有两个组件,它们具有相同的服务类型(接口)和两个不同的实现,并且将用两个不同的标识符进行标记:
Now you've both controls registered in your inversion of control container, and you can use own-API component retrieval factory like this: 现在,您已经在控件容器的反转中注册了两个控件,并且可以使用自己的API组件检索工厂,如下所示:
IoCFactory.GetComponents<IControl>()
. IoCFactory.GetComponents<IControl>()
。 You want all IControl implementations in current inversion of control's container - not recommended in your case! 您希望当前的控件容器反转中的所有IControl实现-在您的情况下不建议使用! -. -
IoCFactory.GetComponent<IControl>("WindowsTextBox")
. IoCFactory.GetComponent<IControl>("WindowsTextBox")
。 You want the IControl implementation called "WindowsTextBox". 您需要名为“ WindowsTextBox”的IControl实现。
In the second case, which is our focus now, you get an object typed as IControl , meaning you can access to its common members (properties, methods, events...). 在第二种情况下,这是我们现在关注的焦点,您将获得一个类型为IControl的对象,这意味着您可以访问其公共成员(属性,方法,事件...)。
Where's the point of inversion of control in your problem? 您的问题中控制权反转的意义在哪里? Note you're using a factory class that would be placed in a shared library so you can use it anywhere, and same for IControl interface. 请注意,您使用的工厂类将放置在共享库中,因此您可以在任何地方使用它,对于IControl接口也是如此。
Right, I guess you need concrete control instances. 是的,我想您需要具体的控制实例。 You can do two things: 您可以做两件事:
Just play with IControl instances and wherever, in a technology-specific logic, cast it to its concrete type - for example, WindowsTextBox - and go on. 只需玩IControl实例,然后在特定于技术的逻辑中将其转换为它的具体类型(例如WindowsTextBox) ,然后继续。
Create as many interfaces that concrete more IControl , so some logic can access to some properties and methods that are closer to the concrete control feature set. 创建尽可能多的界面来具体实现IControl ,以便某些逻辑可以访问一些更接近于具体控件功能集的属性和方法。 An example of that would be a ITextBox interface and get any inversion of control component by this more concrete interface in the same way as I explained above . 一个例子就是ITextBox接口,并通过这个更具体的接口以与我上面解释的相同的方式获取控件组件的任何反转 。
I believe I gave enough hints in order to get an idea of how my solution structure and assembly organization, plus inversion of control, can give you such technology independence that you're looking between and within your project's layers! 我相信我给出了足够的提示,以便了解我的解决方案结构和组装组织以及控制反转如何为您提供这种技术独立性,使您可以在项目的各个层之间或内部进行查看! ;) ;)
Add a Controlmanager to core with a method RegisterControls. 使用方法RegisterControls将Controlmanager添加到核心。 Webcore calls the Controlmanager.RegisterControls method. Webcore调用Controlmanager.RegisterControls方法。 The main app only talks to core 主应用仅与核心对话
You should use a different factory in the WinForms project and in the Web project. 您应该在WinForms项目和Web项目中使用其他工厂。 Create a IControlFactory
interface that is implemented in both factories, and instantiate the appropriate type of factory in each project. 创建在两个工厂中都实现的IControlFactory
接口,并在每个项目中实例化适当的工厂类型。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.