5

I'm running a WCF application CoreApplication whose VS project has a reference to AncillaryProject. CoreApplication uses a class Provider from AncillaryProject; however, it is never explicitly referenced - it's invoked via Reflection.

My problem is that sometimes CoreApplication fails to find Provider because AncillaryProject does not come up in the call to GetAssemblies(). Sometimes it works fine, but sometimes (I'm guessing it may be after a JIT) it fails.

Here's my original code:

var providers = from d in AppDomain.CurrentDomain.GetAssemblies()
                from c in d.GetTypes()
                where typeof(BaseProvider).IsAssignableFrom(c)
                select c;

After looking at this question, I tried using GetReferencedAssemblies():

var allAssemblies = AppDomain.CurrentDomain.GetAssemblies();
foreach (var a in AppDomain.CurrentDomain.GetAssemblies())
{
    allAssemblies = allAssemblies.Union(
                          a.GetReferencedAssemblies()
                           .Select(b => System.Reflection.Assembly.Load(b)));
}
var providers = from d in allAssemblies
                from c in d.GetTypes()
                where typeof(BaseProvider).IsAssignableFrom(c)
                select c;

I realize that the question I referenced solves the problem through dynamically loading all dll files in the bin directory, but that doesn't sound particularly good to me. Is there a better way to do this, or is .NET simply not loading the other Assemblies in at all? How does this work under the hood, and is there anything I can do about it?

Community
  • 1
  • 1
eouw0o83hf
  • 9,438
  • 5
  • 53
  • 75
  • 1
    It won't completely answer your question, but there is some relevant info in my answer to this question: http://stackoverflow.com/questions/9947882/get-assemblies-without-instantiating-them/9948404#comment12730056_9948404 Other than noting that "referenced" assemblies in VisualStudio don't mean much at runtime, the answer below about using Fusion Logger is a good help too. You should be able to just copy AncillaryProject.dll to wherever Fusion is looking for assemblies, but it might provide some answers as to where it is looking. – CodingWithSpike Apr 09 '12 at 22:05
  • Ahh - that gives me exactly the information I need to know. – eouw0o83hf Apr 11 '12 at 19:39
  • Follow-up for anyone who finds this question: in the intervening years since asking it, I realized that I was going about this in completely the wrong way. Sometimes being less magical and explicitly listing out the `Type`s you want is far, far better. This is one of those situations. – eouw0o83hf Dec 16 '16 at 16:17

3 Answers3

9

According to Microsoft documentation AppDomain.CurrentDomain.GetAssemblies() gets the assemblies that have been loaded into the execution context of this application domain. About AppDomain.CurrentDomain.GetAssemblies()

It seems that you need to change strategy of loading the assemblies you need from using the appdomain to looking for dlls in your applications folder.

I found a discussion on a similar problem here

horgh
  • 17,918
  • 22
  • 68
  • 123
Adil
  • 146,340
  • 25
  • 209
  • 204
3

You should download the .NET Development SDK and start up FuslogVw.exe (fusion log viewer). It will report on CLR Application trying to resolve .NET dependencies. It will show you were it is looking and how it evaluates the candidates located at those places.

Tormod
  • 4,551
  • 2
  • 28
  • 50
3

You can handle the AssemblyResolve event and load AncillaryProject.dll in that event handler

http://msdn.microsoft.com/en-us/library/ff527268.aspx

Eric J.
  • 147,927
  • 63
  • 340
  • 553