[rdnzl-devel] Fixed Assembly Resolver Example

Seth Burleigh seth at tewebs.com
Sun Feb 14 23:47:43 UTC 2010


When attempting to use the import assembly example from
http://common-lisp.net/pipermail/rdnzl-devel/2008-February/000192.html

I was having trouble. Basically, the fullname of the assembly was being
passed in after I had officially loaded the assembly (it happens one
time after attempting to create a new object in the assembly) and it was
then trying to load something like AnAssembly, Culture=Neutral .dll 

So here i fixed  it and you should do something like this to use it:
(assembly-path! "C:/path/to/assembly/directory/" "/another/directory/")
(install-assembly-resolver)

I took the liberty of making install-assembly-resolver uninstall the
previous assembly resolver if there were any. This is most likely the
desired behavior since you dont want to install the same function each
time.
-------------- next part --------------
;;EXPORT 
;;(install-assembly-resolver)
;;(assembly-path! "C:/path/to/assemblies1" ...)
;;automatically uninstalls previous assembly resolver when
;;calling (install-assembly-resolver)
;;FIXES bug in which assembly-name is passed to assembly-resolver
;;in fullname, thus the function attempts to find wrong dll name.

(in-package :rdnzl-user)

;;; Adds additional paths to the search-path used by the
;;; assembly-loader; so that e.g. (load-assembly x) will search for x
;;; not only in the system and  application directories, but also in
;;; every directory in *additional-assembly-directories*
;;;
;;;  Example:
;;;   RDNZL-USER 3 > (load-assembly "AproposGui")
;;;   Warning: Returning NULL object from .NET call
;;,   NIL
;;;   RDNZL-USER 4 > (pushnew (translate-logical-pathname #P"rdnzl:examples;")
;;;                           *additional-assembly-directories*)
;;;   RDNZL-USER 5 > (install-assembly-resolver)
;;;   #<RDNZL::CONTAINER System.ResolveEventHandler #xBD6E28>
;;;   RDNZL-USER 6 > (load-assembly "AproposGui")
;;;   #<RDNZL::CONTAINER System.Reflection.Assembly #xBD7078>
;;;
;;; Alternative method of loading an assembly that doesn't lock the
;;; assembly file:
;;; byte[] asm = File.ReadAllBytes(asmPath);
;;; return Assembly.Load(asm);

(defparameter *additional-assembly-directories* nil)

(defun assembly-path! (&rest args)
  (loop for arg in args do(pushnew arg *additional-assembly-directories* :test #'equal))

*additional-assembly-directories*)

(defun assembly-resolver (app-domain resolve-event-args)
  (declare (ignore app-domain))
  (let ((assembly-name (property resolve-event-args "Name")))
    (loop 
     with parsed-name = 
(let ((comma-pos (position #\, assembly-name)))
  (if comma-pos (subseq assembly-name 0 comma-pos) assembly-name))

	with filename = (make-pathname :name parsed-name :type "dll")
	for dir in *additional-assembly-directories*
	for dirpath = (if (pathnamep dir) dir (parse-namestring dir))
	for path = (merge-pathnames dirpath filename)
	when (probe-file path)
        do
        (let*
            ((evidence
              (property
               (invoke "System.Reflection.Assembly" "GetExecutingAssembly")
               "Evidence"))
             (assembly
              (invoke "System.Reflection.Assembly" "LoadFile" (namestring path) evidence)))
          (return-from assembly-resolver assembly))
	finally (return (make-null-object "System.Reflection.Assembly")))))


(defvar *assembly-resolve-handler* nil)


(defun install-assembly-resolver (&optional (handler #'assembly-resolver))
  (let ((my-domain (property "System.AppDomain" "CurrentDomain"))
	(assembly-resolve-delegate (new "System.ResolveEventHandler" handler)))

(when *assembly-resolve-handler* 
  (uninstall-assembly-resolve-handler 
   *assembly-resolve-handler*) 
  (setf *assembly-resolve-delegate* assembly-resolve-delegate))

    (prog1 assembly-resolve-delegate
      (invoke my-domain "add_AssemblyResolve" assembly-resolve-delegate))))

(defun uninstall-assembly-resolve-handler (handler)
  (invoke (property "System.AppDomain" "CurrentDomain") "remove_AssemblyResolve" handler)
(setf *assembly-resolve-handler* nil))


More information about the rdnzl-devel mailing list