2010-03-13 69 views
3

我们在WCF服务上有一个插件系统,用于检查位于bin文件夹中的库是否存在某些装配级属性并加载它们。这允许基于哪个客户端正在进行呼叫来定制某些服务呼叫。这在大多数情况下都很有效。但是,有时它似乎失去了dll,这导致服务恢复到每个客户端的默认实现。到目前为止,解决方案只是将dll文件移出bin文件夹,然后重新进入。这会导致asp.net拿起该文件,并且自定义设置再次开始工作。ASP.NET在bin目录中忘记dll

我不知道为什么在一段时间之后会议会这样错过。任何想法可能会导致这种情况?

编辑:问题说明更清楚

我们的服务使用服务工厂来伸手,基于什么客户端调用代码自定义实现。如果没有自定义实现,我们发布默认实现。我们使用GetAssemblies来检查装配了一个属性的程序集,该属性将它们指定为自定义实现并将它们与客户端关联起来。问题是GetAssemblies会停止返回客户端的自定义程序集,即使该库仍保留在bin文件夹中。将dll从bin中移出,并回到它将解决问题大约一个星期,直到它再次发生为止

+0

*什么*不再使用自定义实现?你的代码?你的意思是GetAssemblies()调用不会返回你认为应该返回的程序集?这个问题没有很清楚的描述。 – Cheeso 2010-03-23 19:41:20

+0

我们的服务使用服务工厂来根据客户端调用代码来发布自定义实现。如果没有自定义实现,我们发布默认实现。我们使用GetAssemblies来检查装配了一个属性的程序集,该属性将它们指定为自定义实现并将它们与客户端关联起来。问题是GetAssemblies会停止返回客户端的自定义程序集,即使该库仍保留在bin文件夹中。将dll从bin中移出,然后回到它将解决该问题约一周,直到它再次发生。 – 2010-03-23 21:13:50

+0

您是否在事件日志中收到任何错误或警告消息?此外,该盒子上运行的任何防病毒软件? – SoftwareGeek 2010-03-25 02:27:34

回答

4

您遇到的问题必须与自动回收appdomain有关。显然AppDomain的回收行为与真正的重启行为不同。在回收时,它只会加载明确引用并根据需要加载的dll。看到这个链接 http://www.chrisvandesteeg.nl/2006/06/15/appdomain-recycle-different-from-real-restart/

GetAssemblies将只返回当前加载到appdomain中的程序集的事实,这可以解释您在程序中获得的异常。为了安全起见,如果您正在处理插件类型库,则应始终使用Assembly.LoadFrom扫描插件文件(dll)并显式加载它们。另一种方法是在自定义主机(例如窗口服务)中从外部托管WCF服务,以使主机的生命周期不受IIS回收策略的限制。

阅读本上的AppDomain回收 http://blogs.msdn.com/tess/archive/2006/08/02/asp-net-case-study-lost-session-variables-and-appdomain-recycles.aspx

+0

没有接受选项了。这将是我会接受的答案。 – 2010-03-31 15:54:32

+0

可惜,我没有得到赏金:页 – 2010-04-01 04:03:02

0

如何加载程序集?下一个问题......为什么? bin目录中的程序集应自动加载并可供引用它们的ASP.NET应用程序使用。也许你在这里遇到了一些冲突......也就是说,访问被拒绝,因为一些其他线程/进程对程序集有一个打开的句柄。对不起,这是如此含糊,但这是唯一立即想到的事情。你可以使用FileMon或类似的工具来检查它。

另外...你是什么意思的“失去”DLL?你正在调用一些特定的方法来找到它,并失败?什么是错误?你是否检查过事件查看器未处理的异常?

+0

我们调用AppDomain.CurrentDomain.GetAssemblies()并检查它们是否有正确的属性。如果他们这样做,那么我们使用它而不是默认的实现。通过“失去”我的意思是它不再使用自定义实现,而只是使用默认值。 – 2010-03-14 00:49:24

+0

*什么*不再使用自定义实现?你的代码?你的意思是GetAssemblies()调用不会返回你认为应该返回的程序集?这个问题没有很清楚的描述。 – Cheeso 2010-03-23 19:39:04

+0

我以为程序集是懒加载的。我们在这里有一个应用程序,它需要一些提示来看看需要什么程序集,因为核心应用程序没有直接引用它。 – Ant 2010-03-24 03:30:24

0

GetAssemblies仅返回已加载的程序集列表。如果您尚未使用该程序集中的类型,则该程序尚未加载。您需要使用Assembly.Load从磁盘加载所需的程序集;/bin文件夹中的程序集不会自动加载到应用程序域中。

此外,您可能会考虑使用Managed Extensibility Framework (MEF),它专门用于处理您正在讨论的功能。

0

大会提示路径进行检查只有一次,当你的AppDomain负载,即使你明确告诉它通过名字来加载程序集也不会发现它的更多信息。为了解决这个问题,你需要重新加载你的主要AppDomain,或者创建一个辅助AppDomain并使用它来加载你的程序集,这是我在过去所做的并且工作正常。但它承担了第二个AppDomain的开销,并不确定这是否是一件大事。