i'm writing visual studio extension , i'm confused how , , when it's loading assemblies. have this:
my visual studio extension project (let's call myextension
) references several assemblies including assembly called foo.dll
.
myextension
contains class called foomanager
instantiated in response menu item being clicked.
when foomanager
instantiated passed output path of project in current solution , creates appdomain should load assembly, this:
public foomanager(string assemblypath) { // actual applicationbase of current domain 1 of vs , // not of plugin // need our new appdomain able find our assemblies // without createinstanceandunwrap fail var p = system.io.path.getdirectoryname(assembly.getexecutingassembly().location); var cachepath = path.combine(p, "cache"); var pluginpath = path.combine(p, "test"); if (directory.exists(cachepath)) { directory.delete(cachepath, true); } if (directory.exists(pluginpath)) { directory.delete(pluginpath, true); } directory.createdirectory(cachepath); directory.createdirectory(pluginpath); var newpath = path.combine(pluginpath, path.getfilename(assemblypath)); file.copy(assemblypath, newpath, true); var setup = new appdomainsetup() { applicationbase = p, shadowcopyfiles = "true", shadowcopydirectories = pluginpath, cachepath = cachepath }; domain = appdomain.createdomain("mytest_appdomain", appdomain.currentdomain.evidence, setup); // foocollection defined in myextension. has several references // things defined in foo.dll - used mef load assembly // referenced pluginpath collection = domain.createinstanceandunwrap( typeof(foocollection).assembly.fullname, typeof(foocollection).fullname, false, bindingflags.default, null, new object[] { pluginpath }, null, null) foocollection; }
now 1 property of foomanager
looks (fooinfo
defined in foo.dll
):
public ienumerable<fooinfo> spiders { { return collection.foos.select(s => s.metadata); } }
but when try access system.argumentexception
message object type cannot converted target type.
know happens if 2 copies of same assembly loaded different locations, , think, ultimately, that's what's happening here, can't figure out how load same place.
so after struggling lot (and above latest attempt), thought maybe serialize byte[]
, deserialize again way avoid problem types, tried this:
var msgbytes = collection.serializefooinfo(); var msg = fooinfo.deserializemessage(msgbytes);
where serialize , deserialize use binaryformatter
(the classes marked serializable
). serialization seems work, on deserialization, when here:
public static list<fooinfo> deserializemessage(byte[] source) { using (var stream = new memorystream(source)) { binaryformatter formatter = new binaryformatter(); var msg = formatter.deserialize(stream); return msg list<fooinfo>; } }
msg
comes null. if try run in debugger using immediate window, see deserialize
threw filenotfoundexception
message:
cannot load assembly 'c:\users\matt.burland\appdata\local\microsoft\visualstudio\14.0exp\projectassemblies\qesxy6ms01\foo.dll'
but don't understand path came from. it's not extension has been installed, c:\users\matt.burland\appdata\local\microsoft\visualstudio\14.0exp\extensions\mycompany\footools\1.0
, set applicationbase
appdomain
, contains file foo.dll
. why trying load other mystery location? other location seems created dynamically , contains foo.dll
assembly.
i've similar in windows service (and using lot of same classes) , works fine, seems particular way visual studio extensions. can shine light here?
so thought might help: http://geekswithblogs.net/onlyutkarsh/archive/2013/06/02/loading-custom-assemblies-in-visual-studio-extensions-again.aspx
but if try attach assemblyresolve handler in package class suggested doesn't called interesting (which isn't surprising, it's not domain i'm try load from), if try attach new domain create if try this:
domain.assemblyresolve += onassemblyresolve;
then fails because foomanager
isn't marked serializable. created proxy binding assemblyresolve
, assemblyresolve
never fires. tried not setting applicationbase
when creating domain, thinking force have try resolve, can't create proxy class in created domain because doesn't know load assembly from!.
Comments
Post a Comment