Here is a very basic idea of how it can be implemented (I did not run or
compiled this code....)
public class AssemblyInspector
{
private static System.Collections.Hashtable typeInfoTable = new System.Collections.Hashtable(500);
public AssemblyInspector()
{
}
public void Analyse(System.String assemblyPath)
{
System.AppDomain domain = System.AppDomain.CreateDomain(System.Guid.NewGuid().GetHashCode().ToString());
try
{
//Use AssemblyName so the assembly will not be loaded in the current appdomain.
System.Reflection.AssemblyName assemblyName = System.Reflection.AssemblyName.GetAssemblyName(assemblyPath);
//load the assembly in the newly created appdomain
domain.Load(assemblyName.Name);
//Execute inspection "inside" the appdomain.
System.CrossAppDomainDelegate del = new CrossAppDomainDelegate(Analyse);
domain.DoCallBack(del);
}
finally
{
if(domain != null)
{
//Unload appdomain.
System.AppDomain.Unload(domain);
}
}
}
private void Analyse()
{
//Create a hashtable for each appdomain
System.Collections.Hashtable isolatedTypeInfo = new System.Collections.Hashtable();
//add the current type info for each appdomain and index it by appdomain
friendly name.
typeInfoTable.Add(System.AppDomain.CurrentDomain.FriendlyName, isolatedTypeInfo);
//Load all assemblies from "this" appdomain.
System.Reflection.Assembly[] assemblies = System.AppDomain.CurrentDomain.GetAssemblies();
//inspect
foreach(System.Reflection.Assembly assembly in assemblies )
{
System.Type[] types = assembly.GetTypes();
foreach(System.Type type in types)
{
//extract whatever you need from the type and
//add to the isolatedTypeInfo table.
}
}
}
public System.Object GetResults()
{
//after inspecting more than one assembly,
//you can use some logic to "intersect all hashtables in typeInfoTable
//and return it here.
return null;
}
}
You need to make sure that code executed in other appdomains dont "bleed"
foreign types into the current appdomain otherwise you may end up loading
that assembly. use DoCallBack to execute arbitrary code in other appdomain
and extract data via either a static structure (like a hashtable) or using
AppDomain.SetData(....) and AppDomain.GetData(...). this approach will give
you isolation and is often used by addin or pluggin projects where it is
important not loading the wrong stuff and most important of all, giving the
ability to unload an entire appdomain that may have several unwanted assemblies...
Erick Sgarbi
[quoted text, click to view] > Thanks for your reply. I have not worked with AppDomains so far so may
> be I
> miss the point.
> What I want to do: after loading assemblies - have a list of old types
> and
> have a list of new types and compare:
> for every old type: is there a new type with the same name - if so -
> compare
> fields (name and type)
> and keep the result (e.g. type "MyClass": field "x" has changed to "y"
> and
> field "z" has been added).
> So I would have to pass a type to the other AppDomain. Is this
> possible?
>
> Hans-Peter
>
> <erick@csharpbox.com> wrote in message
> news:9de69f363998c7610b1bc3ae2c@msnews.microsoft.com...
>>> - is there any detailed information about loading assemblies and
>>> types
>>>
>> About assemblies you can compare versions without loading them into
>> your appdomain by using AssemblyName.GetAssemlbyName(...path..):
>>
>> System.Reflection.AssemblyName.GetAssemblyName(assemblyPath).Version
>>
>> Types, are a differrent thing all together as you will need to load
>> the
>>
> assembly
>
>> in order to investigate about the type. ... look next...
>>
>>> - is there a simple way to load all those types parallel
>>>
>> Once you load an assembly you can not unload it however, you can
>> unload
>>
> appdomain,
>
>> so the answer is yes you can load types in parallel but you will have
>> to create another two appdomains and do the dirty work there and
>> unload them when you're done.
>>
>> System.AppDomain domain1 = System.AppDomain.CreateDomain("Temp1");
>> domain1.Load("...assembly...");
>> //Load any types into the appdomain and investigate by using
> CrossAppDomainDelegate.
>
>> System.AppDomain.Unload(domain1);
>>
>> This approach is very usefull since it will not load the assembly
>> into
>>
> your
>
>> defaultappomain (current) consequently you will not have unwanted
>>
> assemblies
>
>> loaded into your default appdomain.
>>
>> Erick Sgarbi
>>
>>> I want to write a utility that compares different releases of an
>>> application. The idea is to have two directories, one containing the
>>> assemblies of the "old" release and another one with the "new"
>>> assemblies.
>>> So many assemblies will have the same name but different versions -
>>> some
>>> with changes some without. Actually the assemblies are not strongly
>>> named.
>>> The utility should load all assemblies of the old release and all
>>> assemblies
>>> of the new release and compare all the included types. "Compare the
>>> types"
>>> means to compare some properties of the FieldInfo of the types like
>>> FieldType and Name.
>>> My problem is: there are different methods to load an assembly and I
>>> don't
>>> understand the difference and inclusion in detail. Using LoadFrom
>>> works fine
>>> for the first set of assemblies but doesn't load the assembly again,
>>> even
>>> with a different path. That is what I expected reading the
>>> documentation.
>>> When using LoadFile the creation of all the types fails even reading
>>> the
>>> first set because of types using referenced assemblies. May be I
>>> missed
>>> something how to do it.
>>> Can anyone tell me:
>>> - is there any detailed information about loading assemblies and
>>> types
>>> - is there a simple way to load all those types parallel
>>> - will it change in Framework 2.0
>>> thanx
>>> Hans-Peter