2009-03-27 18 views
0

Ich habe eine Website, die auf Benutzeranforderung kompiliert eine Klasse im laufenden Betrieb und legt die DLL (namens Equation.dll) in einem Unterverzeichnis der Website. Der Administrator kann jederzeit neu kompilieren. Sobald jedoch eine Instanz der Klasse erstellt wurde, wird die Meldung "Der Prozess kann nicht auf die Datei zugreifen, weil sie von einem anderen Prozess verwendet wird" angezeigt.Verwenden einer AppDomain zum Instanziieren einer Klasse in einer DLL

Wie ich es verstehe, ist der einzige Weg um Instanzen aus einer anderen AppDomain zu erstellen. Das nächste Mal, dass der Administrator neu kompilieren muss, muss ich diese AppDomain entladen und (denke ich) alles wird gut. (Vielleicht ist meine Annahme falsch?)

Ehrlich gesagt kann ich keine Instanz dieser Klasse erstellen, um mein Leben zu retten. Zugegeben, ich bin hier ein bisschen über meinen Kopf hinweg ... also schwinge ich bei allem. Mein Schnipsel an diesem Punkt ist:

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"); 

Der „equationcache“ Ordner ist, wo die DLL kompiliert wird (obwohl ich versucht habe, setzen diese in „ist“ zum Spaß, und kein Erfolg entweder). Der Assemblyname im Aufruf scheint korrekt zu sein (und funktioniert mit einer appDomain.Load). Der Typname in dem Aufruf scheint korrekt zu sein. Gemäß dem Protokoll, geschieht Folgendes:

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

Ich verstehe nicht, warum es für verschiedene Formen von „Cnn.CostModel“ im „equationcache“ Verzeichnis. Zugegebenermaßen lebt der aufrufende Code in der "Cnn.CostModel.dll" im bin-Ordner. Was muss ich tun, um die Datei "Equation.dll" abzurufen?

Oder bin ich einfach völlig von der Basis auf dieses Unterfangen? Sehr frustriert. Jede Hilfe wäre sehr geschätzt.

Antwort

0

Was Sie sehen, ist .NET versuchen, Ihre aufrufende DLL (Cnn.CostModel.dll) zu binden. Ich vermute, dass die Equation.dll auf einen Typ in Ihrer Haupt-DLL verweist und deshalb versucht die AppDomain, die Sie erstellen, diese zu laden.

1

Ich weiß nicht viel über AppDomains, per se, aber Ihr grundlegendes Problem klingt sehr ähnlich dem, das MEF erstellt wurde, um zu lösen. Ich war mir nicht sicher, ob es Ihre spezifischen Anforderungen ansprechen würde, aber Glenn Block's Kommentar zu this post scheint darauf hinzudeuten, dass dies der Fall wäre. Vielleicht ist es einen Blick wert, wenn Sie mit Ihrer aktuellen Architektur nicht zu weit entfernt sind.

+0

ich in den MEF ... Dank aussehen werden! –

0

fehlt Ihnen ein Stück Arbeit. Sie haben die neue Anwendungsdomäne erstellt, aber bevor Sie eine Klasse dort instanziieren können, müssen Sie die Assembly, in der sich die Klasse befindet, in Ihre neue Anwendungsdomäne laden. Anschließend können Sie versuchen, eine Instanz daraus zu erstellen.

Aus dem Aussehen Ihres Beispiels, Gleichung ist der Name der Assembly, die Sie laden müssen, was ist der Name der Klasse, die Sie erstellen möchten?

Rick Strahl hat einige gute Informationen darüber, wie all dies zu tun, sein, wo ich gelernt aus:

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