2009-03-27 7 views
0

J'ai un site Web qui, à la demande de l'utilisateur, compile une classe à la volée et dépose la DLL (appelée Equation.dll) dans un sous-répertoire du site Web. L'administrateur peut recompiler à tout moment. Cependant, une fois qu'une instance de la classe a été créée, le message "Le processus ne peut pas accéder au fichier parce qu'il est utilisé par un autre processus" est affiché. Si je comprends bien, la seule façon de contourner cela est de créer des instances à partir d'un AppDomain différent. La prochaine fois que l'administrateur doit recompiler, je devrai décharger ce domaine d'application et (je pense) tout ira bien. (Peut-être que mon hypothèse est fausse?)Utilisation d'un AppDomain pour instancier une classe dans une DLL

Franchement, je ne peux pas créer une instance de cette classe pour me sauver la vie. Certes, je suis un peu dans la tête ici ... alors je me balance à tout. Mon bout à ce moment est:

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

Le dossier « equationcache » est où le dll est compilé (bien que je l'ai essayé de placer cela dans « bin » pour le plaisir, et sans succès non plus). Le nom de l'assembly dans l'appel semble être correct (et il fonctionne avec un appDomain.Load). Le nom du type dans l'appel semble être correct. Selon le journal, ce qui suit se produit:

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

Je ne comprends pas pourquoi il est à la recherche de différentes formes de « Cnn.CostModel » dans le répertoire « equationcache ». Certes, le code appelant réside dans le "Cnn.CostModel.dll" dans le dossier bin. Que dois-je faire pour récupérer le fichier "Equation.dll" à la place? Ou est-ce que je suis tout à fait hors de la base de cet effort? Très frustré. Toute aide serait grandement appréciée.

Répondre

0

Ce que vous voyez est .NET essayant de lier votre DLL appelant (Cnn.CostModel.dll). Je devine que l'Equation.dll référence un certain type dans votre DLL principale et c'est pourquoi l'AppDomain que vous créez essaie de le charger.

1

Je ne sais pas grand-chose sur AppDomains, en soi, mais votre problème fondamental ressemble beaucoup à celui que MEF a été créé pour résoudre. Je ne savais pas si cela répondrait à vos besoins spécifiques, mais le commentaire de Glenn Block à this post semblerait indiquer que ce serait le cas. Peut-être que cela vaut le coup d'oeil si vous n'êtes pas trop loin sur la route avec votre architecture actuelle.

+0

Je vais regarder dans le ... merci MEF! –

0

Il vous manque quelque chose. Vous avez créé le nouveau domaine d'application, mais avant de pouvoir y instancier une classe, vous devez charger l'assembly dans lequel réside cette classe dans votre nouveau domaine d'application, puis vous pouvez tenter de créer une instance à partir de celui-ci. De l'apparence de votre exemple, Equation est le nom de l'assemblage que vous voulez charger, quel est le nom de la classe que vous voulez créer?

Rick Strahl a de bonnes informations sur la façon de faire tout cela, son où j'appris de:

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

Questions connexes