tags:

views:

468

answers:

6

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. 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. 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.

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. The problem is that GetAssemblies stops returning a client's custom assembly even though the library remains in the bin folder. Moving the dll out of bin, and back into it will fix the issue for about a week until it happens again

A: 

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. 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.

Also... what exactly do you mean by "lose" the 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?

Bryan
We're calling AppDomain.CurrentDomain.GetAssemblies() and checking them to see if any have the correct attribute. If they do, then we use it instead of the default implementation. By "lose" I mean it no longer uses the custom implementation, and just uses the default instead.
Timothy Strimple
*what* no longer uses the custom implementation? Your code? Do you mean the GetAssemblies() call doesn't return the assemblies you think it should return? The problem isn't very clearly described.
Cheeso
I thought assemblies were lazy loaded. We had an application here that required some hints as to what assemblies to look at, because the core application had no direct reference to it.
Ant
He is using REFLECTION to dynamically load the assemblies.
SoftwareGeek
A: 

Is your app pool recycling and by-passing your AppDomain.CurrentDomain.GetAssemblies call?

rick schott
The GetAssemblies call is called for each web service request, so I don't think app pool recycling would cause it to bypass the GetAssemblies call.
Timothy Strimple
-1 Cos this is not an answer.
Restuta
A: 

GetAssemblies only returns a list of the Assemblies already loaded. 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; the assemblies in the /bin folder are not automatically loaded into the app domain.

Also, you might look into using the Managed Extensibility Framework (MEF), it was designed specifically to handle the functionality you're talking about.

Robert C. Barth
A: 

...replacing an assembly in a \bin directory will cause a whole new batch compile of that directory.

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

Do you have your initialization code in Application_Start inside global.aspx?

Raj Kaimal
+2  A: 

The problem that you are having must be related to the automatic recycling of the appdomain. Apparently appdomain recycle behaves differently from a real restart. On recycle, it will only load dll that is explicitly reference and loaded as needed. See this link 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. 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. 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.

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

Fadrian Sudaman
There is no accept option anymore. This would be the answer I would accept.
Timothy Strimple
Pity too that I didnt get the bounty :p
Fadrian Sudaman
A: 

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. 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. It does however carry the overhead of a second AppDomain, not sure if thats a big deal or not.

emalamisura