0

我正在尝试制作一个棋盘游戏框架,将每个游戏作为它们自己的插件类加载(通过依赖注入)。每个“游戏”都将是它自己的 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);
}

我希望我可以让它不那么开放,但是我能做些什么来解决这个问题并保持我想要的目录结构?- 制作某种形式的自定义加载器以通过插件/递归搜索?- 为二进制序列化选择不同的方法?- 当我“加载”时,我是否没有正确地将类加载到“内存”中以供将来使用?

如果你读到这篇文章并说‘他为什么要那样做?:)

4

1 回答 1

0

1)使用Assembly assembly = Assembly.LoadFrom("dllPath");代替Assembly.LoadFile()

2)由于你的插件有不同的名字,你可以把它们放在一个目录下,并在 app.config 中定义到这个目录的路径。

3)在主 AppDomain 之外加载 Dll 可能是个好主意,这样您就可以在不重新启动应用程序的情况下卸载它们,请参阅我的示例here

于 2012-12-19T23:39:42.163 回答