简体   繁体   中英

C# Hidden References

I am trying to determine which dlls my assemblies need to compile. I have two sample projects, Scratch and ScratchTest both in one solution. Here is Scratch's Program.cs:

using System.ServiceProcess;

namespace Scratch
{
    public class A : ServiceBase
    {
        static void Main(string[] args)
        {
        }
    }
}

Scratch has a reference to System.ServiceProcess.dll.

Here is ScratchTest's program.cs:

namespace ScratchTest
{
    class Program
    {
        static void Main(string[] args)
        {
        Scratch.A o;
        }
    }
}

ScratchTest has to reference BOTH Scratch and System.ServiceProcess.dll. However, the resulting ScratchTest.dll has no reference to System.ServiceProcess.dll, only Scratch. I know this both by looking at

Assembly.GetReferencedAssemblies()

and by using .net reflector. So my question is, how can I tell that ScratchTest requires System.ServiceProcess.dll to compile? Especially considering SratchTest wouldn't necessarily want to reference all of Scratch's references because there might be some conflicting ones. Thanks, Eric

First thing is that the problem that you are facing is not specific to ServiceBase Class. It is pertaining to how exactly CLR detects the type dependencies for a C# program and loads the referenced assemblies. C# compiler is simply giving you an error in advance at compile time itself as the same will fail at run time also when CLR tries to run your program. Here is what I'm assuming while explaining the solution to your problem:

ScratchTest is your start-up project although you have defined two entry points in your solution as Main method is present in both "Scratch" and "ScratchTest" projects. To avoid confusion generally you should have only one main method (entry point) for your solution though it has no impact on your current problem.

Solution : When you refer class A in scratchTest project you are not referring only to class A but the class ServiceBase as well because class "A" is inheriting from it. So when compiler tries to compile your ScratchTest Project it tries to find the dependency types namely "A" and ServiceBase both in the assemblies that are currently referenced. The point of importance here is that CLR always tries to find the dependency types only in the assemblies whose reference is present directly in the manifest meta-data of the assembly itself which you are trying to load (which is ScratchTest in this case). Dependency types are NEVER searched in a recursive fashion the way you have structured your solution. Essentially expecting CLR to search a dependency type in all the referenced assemblies and in turn their referenced assemblies will be hell lot of performance impact at start-up of your .Net application.

At the same time the core .Net libraries like MsCorLib , System , System.Core , System.Data are usually referenced in most of the C# projects you create. Then considering the case otherwise had CLR implemented the logic of recursively finding the dependency types through referenced assemblies then it would have been making an extra effort by making a check every time whether it had already gone past a specific assembly or not while searching a dependency type which would have hurt start-up performance further.

To fix your code you can do following two things :

  • Add reference to System.ServiceProcess.dll to ScratchTest project as advised by the C# compiler.

OR

  • Use the class A in "ScratchTest" project itself as it already contains a reference to System.ServiceProcess.dll

I don't think you need to explicit call System.ServiceProcess on the test file.

The Test file is not using any reference to any method or class inside System.ServiceProcess, just using Scratch.

You do not need to requieres all the libraries that the referenced clases uses, just the one are currently used by your class.

So ScratchTest is only using Scrath and Scratch is using System.ServiceProcess.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM