我有两个项目:引擎,客户端。在执行Engine1.cs类的过程中,我想通过将来自Engine.cs的对象传递给ClientAction类来打开Windows窗体。客户端引用了Engine项目。
namespace Engine {
public Class Engine1 {
public Engine1() {
}
//what I would do if I could reference the Client project
ClientAction.OpenForm(obj1, obj2);
}
}
using Engine;
namespace Client {
public Class ClientAction {
public ClientAction() { }
public OpenForm(object obj1, object obj2) {
Form1.Open(obj1, obj2){
...
}
}
}
}
答案 0 :(得分:1)
您可以使用反射和类System.Activator
(“ mscorlib.dll”程序集)来完成此操作。如下定义类:
在项目 Engine
中using System;
using System.Reflection;
namespace Engine
{
public class Engine1
{
public Engine1()
{
var clientAction = Activator.CreateInstance(
Type.GetType("Client.ClientAction, Client"), new object[] { });
MethodInfo methodInfo = clientAction.GetType().GetMethod("OpenForm");
var arg1 = new object();
var arg2 = new object();
methodInfo.Invoke(clientAction, new object[] { arg1, arg2 });
}
}
}
在项目 Client 中,
类ClientAction
namespace Client
{
public class ClientAction
{
public ClientAction() { }
public void OpenForm(object obj1, object obj2)
{
new Form1()
{
Text = "OpenForm(object obj1, object obj2)"
}.Show();
}
}
}
现在在项目 Client 中,您可以像这样在类Program
中对其进行测试:
using System;
using System.Windows.Forms;
namespace Client
{
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
var engine1 = new Engine.Engine1();
Application.Run(new Form1());
}
}
}
另一种选择是使用委托。您必须在项目 Engine 中创建一个静态事件,并在项目 Client 中为该事件订阅一个处理程序,该处理程序将调用所需的方法。
在项目 Engine
中代表:
namespace Engine
{
public class OpenFormEventArgs
{
public object Obj1 { get; set; }
public object Obj2 { get; set; }
}
public delegate void OpenFormEventHandler(object sender, OpenFormEventArgs e);
}
Engine1
类
namespace Engine
{
public class Engine1
{
public static event OpenFormEventHandler OpenForm;
public Engine1()
{
var obj1 = new object();
var obj2 = new object();
OpenFormEventArgs e = new OpenFormEventArgs() { Obj1 = obj1, Obj2 = obj2 };
OpenForm?.Invoke(this, e);
}
}
}
在项目 Client 中,
类ClientAction
namespace Client
{
public class ClientAction
{
public ClientAction()
{
Engine.Engine1.OpenForm += Engine1_OpenForm;
}
private void Engine1_OpenForm(object sender, Engine.OpenFormEventArgs e)
{
OpenForm(e.Obj1, e.Obj2);
}
public void OpenForm(object obj1, object obj2)
{
new Form1()
{
Text = "OpenForm(object obj1, object obj2)"
}.Show();
}
}
}
现在在项目 Client 中,您可以像这样在类Program
中对其进行测试:
using System;
using System.Windows.Forms;
namespace Client
{
static class Program
{
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
var clientAction = new ClientAction();
var engine1 = new Engine.Engine1();
Application.Run(new Form1());
}
}
}
答案 1 :(得分:0)
您可以在Engine项目中定义一个接口,其中包含用于调用各种操作的方法。客户端创建引擎时,使引擎需要该接口的实例。然后,实现该接口的客户端项目将处理事件,即创建表单。
另一种方法是公开Engine1类中的C#事件。在客户端中订阅这些事件,创建表单。
在两种方法中,由Engine类引发的事件都将在引用的Client项目中进行处理。
当项目紧密耦合时,或者要将值返回给引擎时(C#事件支持多个订阅者,并且订阅是可选的),接口会更好。
答案 2 :(得分:0)
为要传递给客户端的类型创建接口。在客户端项目中找到这些接口。
这样,您只需要从引擎到客户端的一个引用。接口的实现在Engine项目中很简单。
您可以从Engine调用客户端,并传递客户端所需的对象。
这带来了多项改进。您可以实现不同的引擎。客户不需要知道引擎如何工作。而且通常是更清洁,更灵活的设计。
注意:类和接口都应该在自己的文件中。
引擎
using Client;
namespace Engine
{
public class Engine1
{
public Engine1()
{
var myObject = new MyObject
{
SomeProperty = null
};
ClientAction.OpenForm(myObject);
}
}
public class MyObject : IMyObject
{
public object SomeProperty { get; set; }
public void DoSomething()
{
// do something
}
}
}
客户
namespace Client
{
public class ClientAction
{
public ClientAction() { }
public OpenForm(IMyObject myObject)
{
myObject.DoSomething();
Form1.Open(myObject.SomeProperty);
}
}
public interface IMyObject
{
object SomeProperty { get; set; }
void DoSomething();
}
}
答案 3 :(得分:-1)
不,这是不可能的,这表明开发人员的设计选择不正确。
在两个项目/应用程序甚至库之间共享的代码应该在它们自己的单独项目中。通常称为“普通”。
实质上,您将具有以下结构:
[
{
"_id": ObjectId("5a934e000102030405000000"),
"temperature_x": 2,
"temperature_y": 2,
"temperature_z": 0,
"timestamp": 1.553168075444e+12
},
{
"_id": ObjectId("5a934e000102030405000001"),
"temperature_x": 2,
"timestamp": 1.553168075444e+12,
"vibration_x": 21,
"vibration_z": 10
}
]
在此结构中,Project1和Project2可以引用Common并使用相同的代码库。
您应该注意的另一件事是潜在的circular dependencies,例如,如果 ...\MySolution\
Project1\
...
Project2\
...
Common\
CommonClass.cs
中的类依赖于Project1
中的类,而Common
中的类可能会发生Common
依赖于Project1
中的类。