Why do I need to reference a dll that I do not use directly?

I have the source code that I received from an external developer, this code is divided into 4 types of projects: their structure, the environment for my project (allows you to call it "ENV"), the application database (call it "Base" ") and the application itself (about 20 dlls libraries, which I will call "App").

Now I have added another layer to this mess, a dll called AdvanceFeatures. It lies directly below the ENV (over the frame). This dll refers only to the structure, and ENV refers to it. Only ENV uses this AdvanceFeatures dll, while Base and App use only ENV.

As I work here, most of the objects in the application are defined in Base and inherit / implement classes / interfaces in ENV. Also, a small part of these objects (in the application and the database) inherits / implements classes / interfaces from the structure itself (but this is quite rare).

So far, all is well, except for one fact. Compiler requirement I will add a link to the AdvanceFeatures dll from each of the DLLs in the application and from the database.

I do not use AdvanceFeatures outside of ENV, so why do I need these links?

Edit: I created a demo project for this problem. These are the project details:

Assembly: AdvanceFeatures References: Nothing (Reference project-folder is empty) Classes: Decorator, IEnvClass, IDecorator IDecorator contents: namespace AdvanceFeatures { public interface IDecorator { IEnvClass Decorated { get; } void Decorate(); } } IEnvClass contents: namespace AdvanceFeatures { public interface IEnvClass { string Name { get; set; } } } Decorator contents: namespace AdvanceFeatures { public class Decorator : IDecorator { public Decorator(IEnvClass decorated) { Decorated = decorated; } #region Implementation of IDecorator public IEnvClass Decorated { get; set; } public void Decorate() { Decorated.Name = "NewName"; } #endregion } } Assembly: ENV References: AdvanceFeatures (Compiled DLL) Contents of only class SomeEnvClass: namespace ENV { public class SomeEnvClass : AdvanceFeatures.IEnvClass { public string Name { get; set; } private readonly AdvanceFeatures.IDecorator _decorator; public SomeEnvClass(string name) { Name = name; _decorator = new AdvanceFeatures.Decorator(this); _decorator.Decorate(); } public string Foo() { return Name; } } } Assembly: TestBase References: ENV (compiled DLL) Contents of only class SomeEnvExtendingClass: namespace TestBase { public class SomeEnvExtandingClass : ENV.SomeEnvClass { public SomeEnvExtandingClass(string name) : base(name) { } } } 

I get an error message:

Error 1 The type "AdvanceFeatures.IEnvClass" is defined in an assembly that is not referenced. You must add a reference to the assembly "AdvanceFeatures, Version = 1.0.0.0, Culture = neutral, PublicKeyToken = null". E: \ Projects \ Dev \ TestReferenceInheritance \ TestBase \ SomeEnvExtandingClass.cs 3 18 TestBase

Now I know why the DLL should be available for the compiled executable, but why should the developer know the internal work of ENV (more precisely, this inheritance tree) in order to expand it?

+6
source share
3 answers

I read all the answers and comments, so I came up with this example. Maybe this is a little easier to understand. :)

Interfaces.dll

 public interface DoesntAcceptValidAndAccurateAnswersOrComments { bool ImAlwaysRight(); } 

Classes.dll - Interfaces.dll Links

 public class Neowizard : Interfaces.DoesntAcceptValidAndAccurateAnswersOrComments { public bool ImAlwaysRight() { return true; } } 

Program.exe - Classes.dll Links

 public class StackOverflowDotCom { public static void Main() { Neowizard someGuy = new Neowizard(); // CS0012 someGuy.ImAlwaysRight(); } } 

This has to do with the compiler. When he tries to compile Program.exe, he sees an object of type Neowizard. What he also sees is that he implements some kind of interface called DontAcceptValidAndAccurateAnswersOrComments, but without a link to Interfaces.dll he cannot find it, therefore it cannot be compiled because it is an interface that, according to compiler does not exist for the program. Exe.

Because Program.exe uses Neowizard, it must also use everything that Neowizard comes from, which is the interface. This applies not only to interfaces, but also to encapsulation. This is a C # programming language rule that is enforced by the compiler.

If you want to argue more about the matter, then you should contact someone from the C # compiler team with a request about this, but please stop persisting on every answer that tried to help you with your question when their answers are actually quite accurate and well educated.

+8
source

If you have the same assembly

 public class Bar{ ... } 

and in another -

 public class Foo{ public Bar MyBar{get;set;} } 

and in the third -

 public class FooBar{ public Foo {get;set;} } 

then you can write:

 Bar myBar = new FooBar().Foo.MyBar; 

if you didn't tell the compiler about defining a bar, how can it compile the last line of code?

or more accurately answer your question. When using an assembly that refers to another assembly, it is likely that your code may use material from that other assembly directly. if the return type is declared in another assembly or indirectly, when type objects defined in another assembly are used in the implementation of methods or as private fields in the assembly that you refer directly to. The compiler needs to know about these types in order for it to work. He relies on you to tell him where he can find information about these types. That is, add a link

EDIT

To clarify a bit, a rule is not used that requires a reference to the same DLL as the dll used. You must reference a DLL that says the same thing. That is why you can sign dll. Then you guarantee that it is always the same implementation (or at least made by someone with key access)

the ability to use another assembly, however, mandatory requirements are mandatory for a dll / program that uses a dll in the middle. You need to explicitly specify which implementation of this assembly you want to use.

+4
source

There are two possibilities:

  • You can use part of the AdvanceFeatures library without its implementation, for example, at some point get a reference to the class that inherits from the class in AdvanceFeatures. This class can be tiny, you can have an enumeration in AdvanceFeatures, which is returned, for example, by the ENV method.
  • You havenโ€™t done anything like this, and itโ€™s just a fact that the library should still be there. If you do not embed the AdvanceFeature dll in the ENV, you cannot actually use the ENV without using the AdvanceFeature. Usually this simply means that it should be in the same folder as your executable file. It might be worth checking that you have libraries installed to copy local, etc. In their properties or links to their properties.
+1
source

Source: https://habr.com/ru/post/896298/


All Articles