简体   繁体   English

ASP.NET忘记bin目录中的dll

[英]ASP.NET forgets dlls in bin directory

We have a plugin system on a WCF service that checks libraries placed in the bin folder for certain assembly level attributes and loads them. 我们在WCF服务上有一个插件系统,它检查放在bin文件夹中的库以获取某些程序集级属性并加载它们。 This allows customization of certain service calls based on which client is making the call. 这允许基于哪个客户端进行呼叫来定制某些服务呼叫。 This works great most of the time. 这在大多数情况下都很有效。 However, sometimes it seems to lose the dll, which causes the service to revert back to the default implementation for every client. 但是,有时它似乎丢失了dll,这导致服务恢复到每个客户端的默认实现。 The solution so far has been to just move the dll file out of the bin folder, and back in. This causes asp.net to pick up the file and customizations start working again. 到目前为止,解决方案只是将dll文件移出bin文件夹,然后重新进入。这会导致asp.net获取文件并自定义重新开始工作。

I'm at a loss for why the assembly is getting missed like that after a certain amount of time. 我不知道为什么会议在一段时间之后会被错过。 Any ideas as to what might be causing this? 关于可能导致这种情况的任何想法?

Edit: Problem stated more clearly 编辑:问题陈述得更清楚

Our services use a service factory to hand out custom implementations based on what client is calling the code. 我们的服务使用服务工厂根据客户端调用代码的方式分发自定义实现。 If there is not a custom implementation, we hand out a default implementation. 如果没有自定义实现,我们将分发默认实现。 We use GetAssemblies to check for assemblies that are decorated with an attribute designating them as a custom implementation and associating them with a client. 我们使用GetAssemblies来检查使用属性修饰的程序集,将它们指定为自定义实现并将它们与客户端相关联。 The problem is that GetAssemblies stops returning a client's custom assembly even though the library remains in the bin folder. 问题是GetAssemblies停止返回客户端的自定义程序集,即使该库仍保留在bin文件夹中。 Moving the dll out of bin, and back into it will fix the issue for about a week until it happens again 将dll移出垃圾箱并返回垃圾箱会将问题解决大约一周,直到再次发生

The problem that you are having must be related to the automatic recycling of the appdomain. 您遇到的问题必须与appdomain的自动回收相关。 Apparently appdomain recycle behaves differently from a real restart. 显然,appdomain recycle的行为与实际重启的行为不同。 On recycle, it will only load dll that is explicitly reference and loaded as needed. 在回收时,它只会加载显式引用并根据需要加载的dll。 See this link http://www.chrisvandesteeg.nl/2006/06/15/appdomain-recycle-different-from-real-restart/ 请参阅此链接http://www.chrisvandesteeg.nl/2006/06/15/appdomain-recycle-different-from-real-restart/

The fact that GetAssemblies will only return you the assembly that is currently loaded into the appdomain, this can explain the anomaly that you are getting with your program. GetAssemblies只会返回当前加载到appdomain中的程序集这一事实,这可以解释您在程序中遇到的异常情况。 To be safe, if you are dealing with plugin type library, you should always scan the plugin files (dlls) and load them explicitly using Assembly.LoadFrom. 为了安全起见,如果您正在处理插件类型库,则应始终扫描插件文件(dll)并使用Assembly.LoadFrom显式加载它们。 Another alternative is to host your WCF services externally in your custom host such as window service so that the life time of the host is not subject to the IIS recycling policy. 另一种方法是在自定义主机(例如窗口服务)外部托管您的WCF服务,以便主机的生命周期不受IIS回收策略的约束。

Read this for more information on appdomain recycling http://blogs.msdn.com/tess/archive/2006/08/02/asp-net-case-study-lost-session-variables-and-appdomain-recycles.aspx 阅读本文以获取有关appdomain回收的更多信息http://blogs.msdn.com/tess/archive/2006/08/02/asp-net-case-study-lost-session-variables-and-appdomain-recycles.aspx

How are you loading the assemblies? 你是如何加载程序集的? Next question... why? 下一个问题......为什么? Assemblies in the bin directory should automatically be loaded and available to ASP.NET applications that reference them. bin目录中的程序集应自动加载并可供引用它们的ASP.NET应用程序使用。 Perhaps you are getting some conflict here... ie, access is denied because some other thread/process has an open handle to the assembly. 也许你在这里遇到了一些冲突...即访问被拒绝,因为其他一些线程/进程有一个打开的程序集句柄。 Sorry that's so vague, but that's the only thing that immediately springs to mind. 对不起,这太模糊了,但这是唯一让人想起的东西。 You could potentially use FileMon or a similar tool to check this. 您可以使用FileMon或类似工具来检查这一点。

Also... what exactly do you mean by "lose" the DLL? 另外......你究竟是什么意思“丢失”DLL? You are calling some specific method to find it, and it fails? 你正在调用一些特定的方法来找到它,它失败了吗? What is the error? 错误是什么? Have you checked the Event Viewer for unhandled exceptions? 您是否检查了事件查看器中未处理的异常?

GetAssemblies only returns a list of the Assemblies already loaded. GetAssemblies仅返回已加载的程序集的列表。 If you haven't used a type from that assembly, it won't have been loaded yet. 如果尚未使用该程序集中的类型,则尚未加载该类型。 You need to use Assembly.Load to load the assembly you want off disk; 您需要使用Assembly.Load从磁盘加载您想要的程序集; the assemblies in the /bin folder are not automatically loaded into the app domain. / bin文件夹中的程序集不会自动加载到应用程序域中。

Also, you might look into using the Managed Extensibility Framework (MEF) , it was designed specifically to handle the functionality you're talking about. 此外,您可能会考虑使用托管扩展性框架(MEF) ,它专门用于处理您正在谈论的功能。

...replacing an assembly in a \\bin directory will cause a whole new batch compile of that directory. ...替换\\ bin目录中的程序集将导致该目录的全新批处理编译。

http://msdn.microsoft.com/en-us/library/5dws599a(VS.71).aspx http://msdn.microsoft.com/en-us/library/5dws599a(VS.71).aspx

Do you have your initialization code in Application_Start inside global.aspx? 你在global.aspx里面的Application_Start中有你的初始化代码吗?

Assembly hint paths are checked only once when your AppDomain loads, even if you explicitly tell it to load an assembly by name it will not find it. 加载AppDomain时,只会检查一次程序集提示路径,即使您明确告诉它按名称加载程序集也不会找到它。 In order to solve this you need to reload your primary AppDomain, or create a secondary AppDomain and use that to load your assembly, this is what I have done in the past and it works fine. 为了解决这个问题,您需要重新加载主AppDomain,或者创建一个辅助AppDomain并使用它来加载程序集,这是我过去所做的,它运行正常。 It does however carry the overhead of a second AppDomain, not sure if thats a big deal or not. 然而它确实带来了第二个AppDomain的开销,不确定这是不是很重要。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM