Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/281.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 二进制序列化重新加载DLL类_C#_Serialization_Dll - Fatal编程技术网

C# 二进制序列化重新加载DLL类

C# 二进制序列化重新加载DLL类,c#,serialization,dll,C#,Serialization,Dll,我正在尝试制作一个棋盘游戏框架,在每个游戏中加载它们自己的插件类(通过依赖注入)。每个“游戏”都将是它自己的DLL。因此,该插件处理为游戏中的“棋子”加载正确的资源、游戏板的正确图像、游戏需要的任何特殊逻辑等 我建议的文件夹结构是 game.exe plugins/ /plugin1 /textures plugin1.dll /plugin2 /textures plugin2.dll 当你开始一个游戏时,我让

我正在尝试制作一个棋盘游戏框架,在每个游戏中加载它们自己的插件类(通过依赖注入)。每个“游戏”都将是它自己的DLL。因此,该插件处理为游戏中的“棋子”加载正确的资源、游戏板的正确图像、游戏需要的任何特殊逻辑等

我建议的文件夹结构是

game.exe
plugins/
    /plugin1
        /textures
        plugin1.dll

    /plugin2
        /textures
        plugin2.dll
当你开始一个游戏时,我让你使用一个文件管理器来加载正确的dll(将来会进行优化),当其他客户端连接到你时,它会让他们也加载自己的插件,或者如果你没有该游戏的dll,就无法连接

加载代码示例如下所示:

Assembly assembly = Assembly.LoadFile(openPlugin.FileName);

string fullTypeName = "TestPlugin.TestPlugin";
Type dllType = assembly.GetType(fullTypeName);
IPlugin myType = (IPlugin)Activator.CreateInstance(dllType);
我现在使用硬编码字符串作为类型名,但这最终会改变

为了与其他人一起玩,有一种网络体系结构,主要包括使用对象的二进制序列化。问题是,当我取消序列化插件dll中类的对象时,系统希望从文件中重新加载dll。当它尝试重新加载它时,它会遵循正常规则并在exe目录中查找dll(如果我将插件dll移动到主目录,这一切都会起作用)

下面是一个二进制序列化的示例(如果有帮助的话)

public Stream SerializeObject(object obj)
{
    Stream stream = new MemoryStream();

    BinaryFormatter formatter = new BinaryFormatter();

    formatter.Serialize(stream, obj);

    return stream;
}

/// <summary>
/// Deserializes Objects
/// </summary>
/// <param name="stream">Stream containing the binary objects</param>
public T DeserializeObject<T>(byte[] data)
{
    Stream stream = new MemoryStream(data);
    IRemotingFormatter formatter = new BinaryFormatter();

    return (T)formatter.Deserialize(stream);
}
公共流序列化对象(对象obj)
{
Stream=新的MemoryStream();
BinaryFormatter formatter=新的BinaryFormatter();
序列化(流,obj);
回流;
}
/// 
///反序列化对象
/// 
///包含二进制对象的流
公共T反序列化对象(字节[]数据)
{
流=新的内存流(数据);
IRemotingFormatter formatter=新的二进制格式化程序();
返回(T)格式化程序。反序列化(流);
}
我希望我能让它少一些开放性,但是我能做些什么来解决这个问题并保持我想要的目录结构呢? -制作某种形式的自定义加载程序,通过插件进行递归搜索/? -为二进制序列化选择其他方法? -当我“加载”时,是否因为类被加载到“内存”中以供将来使用而没有正确执行

如果你读到这篇文章并问“他为什么要这样做?”,我很欢迎对体系结构进行更改:)

1)使用
Assembly=Assembly.LoadFrom(“dllPath”)而不是
Assembly.LoadFile()

2) 由于插件的名称不同,您可以将它们放在一个目录中,并在app.config中定义该目录的路径


3) 在主AppDomain之外的其他位置加载DLL可能是个好主意,这样您就可以在不重新启动应用程序的情况下卸载DLL,请参见我的示例

我已编辑了您的标题。请参阅“”,其中的共识是“不,他们不应该”。无论如何,是否有对dll进行递归搜索的方法?或者,序列化重新加载我已经加载的dll的根本原因是什么?@步骤2)会通过搜索帮助您,但不确定递归