views:

596

answers:

3

I have a website that on user-demand compiles a class on the fly and deposits the dll(named Equation.dll) in a subdirectory of the website. The administrator can recompile at any time. However, once an instance of the class has been created, the message "The process cannot access the file because it is being used by another process" is displayed.

As I understand it, the only way around this is to create instances from a different AppDomain. The next time the administrator needs to recompile, I will need to Unload this AppDomain and (I think) everything will be fine. (Perhaps my assumption is wrong?)

Frankly, I can't create an instance of this class to save my life. Admittedly, I'm a bit in over my head here...so I'm swinging at anything. My snippet at this point is:

AppDomainSetup ads = new AppDomainSetup();
ads.PrivateBinPath = HttpContext.Current.Server.MapPath("~/equationcache/");
ads.ApplicationBase = HttpContext.Current.Server.MapPath("~/equationcache/");
AppDomain appDomain = AppDomain.CreateDomain("EquationDomain", null, ads);

Object wrapper = appDomain.CreateInstance("Equation, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null", "Cnn.CostModel.Business.CalculationEngine");

The "equationcache" folder is where the dll is compiled to (though I have tried placing this in "bin" for fun, and no success either). The assembly name in the call appears to be correct (and it works with an appDomain.Load). The type name in the call appears to be correct. According to the log, the following happens:

=== Pre-bind state information ===
LOG: User = xxx\xxx
LOG: DisplayName = Cnn.CostModel, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
 (Fully-specified)
LOG: Appbase = file:///C:/Users/xxx/Documents/Visual Studio     2008/Projects/CnnCostModel/CnnCostModels/equationcache/
LOG: Initial PrivatePath = C:\Users\xxx\Documents\Visual Studio 2008\Projects\ACnnCostModel\CnnCostModels\equationcache\Calling assembly : Equation, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null.
LOG: This bind starts in default load context.
LOG: No application configuration file found.
LOG: Using machine configuration file from C:\Windows\Microsoft.NET\Framework\v2.0.50727\config\machine.config.
LOG: Policy not being applied to reference at this time (private, custom, partial, or location-based assembly bind).
LOG: Attempting download of new URL file:///C:/Users/xxx/Documents/Visual Studio 2008/Projects/CnnCostModel/CnnCostModels/equationcache/Cnn.CostModel.DLL.
LOG: Attempting download of new URL file:///C:/Users/xxx/Documents/Visual Studio 2008/Projects/CnnCostModel/CnnCostModels/equationcache/Cnn.CostModel/Apa.CostModel.DLL.
LOG: Attempting download of new URL file:///C:/Users/xxx/Documents/Visual Studio 2008/Projects/CnnCostModel/CnnCostModels/equationcache/Cnn.CostModel.EXE.
LOG: Attempting download of new URL file:///C:/Users/xxx/Documents/Visual Studio 2008/Projects/CnnCostModel/CnnCostModels/equationcache/Cnn.CostModel/Cnn.CostModel.EXE.

I don't understand why it is looking for different forms of "Cnn.CostModel" in the "equationcache" directory. Admittedly, the calling code lives in the "Cnn.CostModel.dll" in the bin folder. What do I need to do to to fetch the "Equation.dll" file instead?

Or am I just entirely off base on this endeavor? Very frustrated. Any help would be GREATLY appreciated.

A: 

What you are seeing is .NET trying to bind your calling DLL (Cnn.CostModel.dll). I'm guessing that the Equation.dll references some type in your main dll and that's why the AppDomain you are creating tries to load it.

Jeremy Wiebe
+1  A: 

I don't know much about AppDomains, per se, but your fundamental problem sound very much like the one that MEF was created to solve. I wasn't sure if it would address your specific requirements, but Glenn Block's comment to this post would seem to indicate that it would. Perhaps it's worth a look if you're not too far down the road with your current architecture.

Daniel Pratt
I'll look into the MEF...thanks!
A: 

you're missing a piece of work. You've created the new appdomain, but before you can instantiate a class there, you have to load the assembly that class resides in into your new AppDomain, then you can attempt to create an instance from it.

From the looks of your sample, Equation is the name of the Assembly you need to load, what is the name of the Class you want to create?

Rick Strahl has some good info on how to do all this, its where I learned from:

http://www.west-wind.com/WebLog/posts/601200.aspx

Stuart Allen