【问题标题】:Replacing assemblies that are loaded only via reflection替换仅通过反射加载的程序集
【发布时间】:2011-06-26 14:03:08
【问题描述】:

在我目前正在进行的项目中,我们有许多仅通过反射实例化的类,并且它们所属的程序集未被任何其他类引用。

此方案允许在运行时替换程序集以扩展/纠正前一个程序集的功能。请注意,在我们的特定情况下,无法使用 MarshalByRefObject,因此同一程序集的不同版本,暴露了具有相同名称但功能不同的类,最终被加载到同一个 AppDomain 中。

我举一个极其简化的例子:考虑下面的接口声明和控制台应用程序

public interface ISomeInterface
{
    string getData();
}

class Program
{
    static void Main(string[] args)
    {
        byte[] lastLibrary = null;
        Assembly lastAssembly = null;

        while (true)
        {
            byte[] theLibrary = File.ReadAllBytes("ClassLibrary1.dll");

            if (lastLibrary == null || !theLibrary.SequenceEqual(lastLibrary))
            {
                lastAssembly = Assembly.Load(theLibrary);
            }

            ISomeInterface obj = lastAssembly.CreateInstance("ClassLibrary1.Class1") as ISomeInterface;

            Console.WriteLine(obj.getData());

            lastLibrary = theLibrary;
            Thread.Sleep(1000);
        }
    }
}

以及以下接口实现(在单独的程序集中):

public class Class1 : ISomeInterface
{
    public string getData()
    {
        return "someText";
    }
}

正如预期的那样,如果我更改 ISomeInterface 的实现(例如,将“someText”更改为“someOtherText”)并将旧的 dll 替换为新的,则使用最新版本。不过,我想知道:这种机制对软件稳定性造成问题的可能性有多大?我的意思是,在我仅通过反射实例化这些类并且没有其他组件引用它们之前,一切是否安全?至于我们的初步测试,看起来一切正常,但我也想听听专家的意见。

我知道在这个特定的例子中,可以使用 MarshalByRefObject 来完成所有事情,但正如我之前所说,我们不可能朝那个方向前进。

【问题讨论】:

    标签: c# reflection plugins


    【解决方案1】:

    这样的事情应该可以正常工作,但我认为您误解了实际发生的情况。

    当您将程序集加载到 AppDomain 中时,只要该 AppDomin 存在,它就从不发布。你要做的是加载一个新的程序集。但是这样做,您不会发布旧版本。例如,如果以前版本的对象仍然存在,它将返回“someText”,即使新创建的对象会返回“someOtherText”。虽然这两个对象的类型名称都是ClassLibrary1.Class1,但它们是不同的类型。

    如果这种行为对您来说是正确的,那么您应该没问题。但是不要忘记所有旧版本仍然加载并保留在内存中,因此这样做实际上会导致内存泄漏。

    【讨论】:

    • 嗨 svick,是的,这将是预期的行为。感谢您澄清我的疑问。
    • @svick 我遇到了您在此处描述的确切问题。我正在通过 exe 加载 dll 来做某事,但是替换 dll 后,旧代码仍然执行。如何解决这个问题?
    • @KDT 我认为您应该对此提出一个新问题。并添加一些细节,包括你究竟为什么要这样做。
    • 嗨@svick,有点延迟响应,但对于未来的搜索者,我相信我的问题与版本控制有关,因为 dll 的版本没有更新并且始终保持在版本 1.0.0.0 上。因此,用具有相同版本的新文件替换文件不起作用,但是重命名旧文件(或删除它)并复制新的 dll 可以完美地工作。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-05-16
    • 2011-03-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多