将对象传递给新应用程序的 string[] arg
Passing objects to string[] arg of a new application
所以我正在处理一个项目,我正在从一个应用程序中启动一个应用程序。
UnitOfWork.Current = new UnitOfWork(new PollerContext());
UnitOfWork.Current.BeginTransaction();
try
{
var launcher = new Launcher();
var arg = launcher.ObjectToString();
System.Diagnostics.Process.Start(@"C:\..\bin\Debug\Emulator.Exe");
}
finally
{
UnitOfWork.Current.Commit();
UnitOfWork.Current = null;
System.Environment.Exit(1);
}
现在我需要将两个对象传递给第二个应用程序,我尝试将它们序列化并将它们作为第二个应用程序的 string[]
参数传递,但它们无法序列化。
这两个对象是 castle.windsor
容器,如果有帮助的话。
是否可以序列化这些代码以便此代码工作,或者是否有其他方法可以做到这一点?
public string[] ObjectToString()
{
var obj = ReturnObjects();
for (int i = 0; i < obj.Length; i++)
{
using (MemoryStream ms = new MemoryStream())
{
new BinaryFormatter().Serialize(ms, obj[i]);
serialize[i] = Convert.ToBase64String(ms.ToArray());
}
}
return serialize;
}
private object[] ReturnObjects() => new object[] { pollerLauncher, backendLauncher };
您将不得不查看进程间通信 (IPC) 协议,但基本上您将不得不自己创建一个低级通信协议(例如通过原始 TCP 套接字),或者(我会建议)利用 WCF 来抽象掉这些细节。
在两个 .NET 应用程序之间直接传递对象的唯一方法是避免将第二个应用程序作为单独的进程启动。就是引用exe调用方法那么简单
当然,这意味着它不会 运行 作为一个单独的进程。但是,如果您希望共享对象,那确实无法避免。唯一的例外是远程处理,它在应用程序之间编组调用 - 但即便如此,也需要您的对象通过继承 MarshalByRefObject
.
进行协作
默认情况下,对象在序列化方面没有多大意义。序列化实际上是关于数据的,所以如果您的对象不仅仅是数据容器,您就有麻烦了。即使容器本身支持序列化,要真正使其工作,您还必须确保它可能实例化的所有可能对象也支持序列化。没有办法通过合同强制执行。即使每个人都支持序列化,契约也会被违反——单例不再是单例,你有很多机会发生冲突和其他错误(例如,一个对象可能创建一个唯一的 id,另一个会引用它,但是当它们被序列化时,第一个将创建一个新的唯一 ID(实际上保持唯一),而第二个将继续引用旧 ID。
但是,大多数 DI 容器也支持通过配置进行设置。这个配置是你可以很容易地在应用程序之间传递的东西,并允许目标重建一个类似的依赖树。
不清楚您实际想要完成什么,所以我无能为力。很可能你正在解决XY问题,第一部分已经完成,所以只剩下不可能的部分。
感谢 Lasse-v-karlsen,我进一步研究了将容器保留在第二个项目中的问题。我只隔离了将在多个项目中使用的部分并将它们安装到容器中。启动其他服务保留在第一个项目中。
所以现在它可以工作了,我不需要额外的参数来启动第二个项目。
所以我正在处理一个项目,我正在从一个应用程序中启动一个应用程序。
UnitOfWork.Current = new UnitOfWork(new PollerContext());
UnitOfWork.Current.BeginTransaction();
try
{
var launcher = new Launcher();
var arg = launcher.ObjectToString();
System.Diagnostics.Process.Start(@"C:\..\bin\Debug\Emulator.Exe");
}
finally
{
UnitOfWork.Current.Commit();
UnitOfWork.Current = null;
System.Environment.Exit(1);
}
现在我需要将两个对象传递给第二个应用程序,我尝试将它们序列化并将它们作为第二个应用程序的 string[]
参数传递,但它们无法序列化。
这两个对象是 castle.windsor
容器,如果有帮助的话。
是否可以序列化这些代码以便此代码工作,或者是否有其他方法可以做到这一点?
public string[] ObjectToString()
{
var obj = ReturnObjects();
for (int i = 0; i < obj.Length; i++)
{
using (MemoryStream ms = new MemoryStream())
{
new BinaryFormatter().Serialize(ms, obj[i]);
serialize[i] = Convert.ToBase64String(ms.ToArray());
}
}
return serialize;
}
private object[] ReturnObjects() => new object[] { pollerLauncher, backendLauncher };
您将不得不查看进程间通信 (IPC) 协议,但基本上您将不得不自己创建一个低级通信协议(例如通过原始 TCP 套接字),或者(我会建议)利用 WCF 来抽象掉这些细节。
在两个 .NET 应用程序之间直接传递对象的唯一方法是避免将第二个应用程序作为单独的进程启动。就是引用exe调用方法那么简单
当然,这意味着它不会 运行 作为一个单独的进程。但是,如果您希望共享对象,那确实无法避免。唯一的例外是远程处理,它在应用程序之间编组调用 - 但即便如此,也需要您的对象通过继承 MarshalByRefObject
.
默认情况下,对象在序列化方面没有多大意义。序列化实际上是关于数据的,所以如果您的对象不仅仅是数据容器,您就有麻烦了。即使容器本身支持序列化,要真正使其工作,您还必须确保它可能实例化的所有可能对象也支持序列化。没有办法通过合同强制执行。即使每个人都支持序列化,契约也会被违反——单例不再是单例,你有很多机会发生冲突和其他错误(例如,一个对象可能创建一个唯一的 id,另一个会引用它,但是当它们被序列化时,第一个将创建一个新的唯一 ID(实际上保持唯一),而第二个将继续引用旧 ID。
但是,大多数 DI 容器也支持通过配置进行设置。这个配置是你可以很容易地在应用程序之间传递的东西,并允许目标重建一个类似的依赖树。
不清楚您实际想要完成什么,所以我无能为力。很可能你正在解决XY问题,第一部分已经完成,所以只剩下不可能的部分。
感谢 Lasse-v-karlsen,我进一步研究了将容器保留在第二个项目中的问题。我只隔离了将在多个项目中使用的部分并将它们安装到容器中。启动其他服务保留在第一个项目中。
所以现在它可以工作了,我不需要额外的参数来启动第二个项目。