Reference namespace from main project - c#

I have a project which has a reference to a "Utilities" project. The "Utilities" project references a 3rd project. All have the same namespace, but I can't do a "using OurNamespace.Utilities.3rdProject" from the main project.
I need to keep it so that all other new projects, only has to reference the "Utilities" project and have access to all other namespaces referenced through it. I can't include all the references on all projects.
/edit (it cascades sort of)
Main Project (references Utilities)
-- Utilities
-- Project with same namespace referenced by Utilities
In Main project, I now need to be able to access the namespace in the project that is referenced within Utilities reference, but without adding it to the main project exclusively.
Edit
"Project 1" references Utilities
using Utilities.Namespace1;
Within Utilities another project is referenced with Namespace2
I want to now access Namespace2 from "Project 1"
using Utilities.Namespace2;
Without having to exclusively reference BOTH in "Project 1" seeing as there will be multiple projects referencing Utilities

If you want to directly use components of an assembly in another assembly, then you need a reference. By "directly" I mean in a strongly-typed way, e.g.:
Creating an instance of a type in the other assembly.
Handling instances of types in the other assembly.
In contrast, "indirect" use is if the Utilities assembly uses the components of 3rd project in the background, but does not publish these e.g. through public properties, arguments of public methods and so on.
To clarify further on assemblies and namespaces: one does not reference namespaces, but assemblies. Namespaces are only used to make type names unique. Namespaces and assembly names are completely independent from each other from a technical perspective (though it is good practice to start the namespaces with the assembly name). So having the same namespace in two assemblies, does not change the situation in any way; if you want to use the types of the other assembly, you still need a reference.
In order to solve your issue, you can either add the reference to 3rd project or if you can't do that, do one of the following:
Add wrappers in the Utilities assembly for the required functionality in the 3rd project. As you already have a reference to the Utilities assembly, you can access these wrappers - as long as you do not access the types of 3rd project directly.
Create another intermediate project that contains the wrappers and reference this.

Related

Converting a C# class I created inside a project to a separate reusable class

I'm not new to C# programming, but I suppose I'm new to programing "the right way" in C#. I've worked in C on embedded devices for years and have written desktop apps to support them. First in VB6, then in C#.
I recently started making better use of classes for reusing code (and for instantiating more than one instance of the class in a program). For example, I "wrapped" a UART interface with some additional functionality so I can use the same code for multiple ports by creating an instance of the class for each one.
It is in a separate file, but still in the same program namespace, so when I want to reuse it, I have to copy the file and change the namespace to the new project.
I'm sure there's a way to create it such that I can just reference it like everything else with either a "using..." reference at the top of the program or with a "Project | References..." checkbox. But for the life of me I can't find a good learning journey for this.
Any direction would help.
You want to create your reuseable class in an assembly - this is the equivalent of a dll from your C experience.
To create an assembly, have a separate project of type assembly (instead of exe) . You can reference the assembly from other projects. If your project is in the same solution you can reference the project, otherwise you can reference the compiled assembly.
C# uses a packaging system called Nuget, so you can package your assemblies into "Nugets" which you host in a Nuget Server. You can then use tooling to discover and import these.
Please create a Class Library project and include your class into that project. Make sure your class is public. Once you build this project you'll get an assembly which can be referenced from other projects. See Tutorial: Create a .NET class library using Visual Studio
There are different ways of referencing it.
You can have the class library project in the same solution as the main project. In this case you should add a project reference.
You can copy the compiled *.dll file to some folder in your solution (e.g. Lib) and add an assembly reference.
If this assembly is to be used in multiple projects please consider creating a NuGet package with this library and pushing it to some repository. Then other projects can add a package reference to this package.
Details:
How to: Add or remove references by using the Reference Manager
Install and manage packages in Visual Studio using the NuGet Package Manager
It is in a separate file, but still in the same program namespace, so when I want to reuse it, I have to copy the file and change the namespace to the new project.
Well, it isn't the best practice but (unfortunatly) still a common behavior. So don't worry to much about it.
What you could do to improve it place the file (and other reusable parts) in a seperated csproj.
For example name the project of the type class library and name it VinDag.Tools. Within the project create a folder UART and place the wrapper there. The namespace of the wrapper would then be VinDag.Tools.UART.
From know on you can just reference the class library instead of renaming the file. It's not necessarily required to be the same namespace as the project.
From there you can start considering (private) nugets. This would prevent you from copying files/csproj around.

how can I consume a dll that is referenced by another dll?

I have three separate projects in my solution. Original and Secondary and Console-app. Secondary assembly references to the Original one and Console-app references to the Secondary. How can I use enumerations (types) in Original assembly from console-app without referencing to it?
Check the shared projects for visual studio.
It allows to have code for multiple projects, each projects compile the shared project as his own code, so you don't need to reference the common code.

Minimize number of copied sub-dependencies (assemblies) by only referencing parts of a class library?

I have a .Net class library that contains many different namespaces and multiple sub-dependencies (referenced assemblies).
Sometimes a project references only one specific namespace, sometimes just one single interface, of such class library but still upon compilation all sub-dependencies (dlls) are copied into my project assembly folder (\bin folder).
So if class library MainClassLibrary references subLib1, sublib2, and sublib3 and when I create a new project that references MainClassLibrary then subLib1.dll, subLib2.dll, and subLib3.dll are also all copied into the binary folder of my project even if I only use an interface definition in a segregated namespace within MainLibrary that does not depend on any of the sub dependencies.
Is the only way to split up the class library into smaller pieces or is there a better, easier way?
even if I only use an interface definition in a segregated namespace within MainLibrary
That is the reason that sometimes only one or a handful of interfaces are put into a separate assembly (Project).
But in general, focus on minimizing the logical dependencies and don't worry to much about how many DLL files are copied.
And as #Alexei mentioned in his comment, this (automated) proliferation of DLL files is the solution to DLL Hell.

Referencing a project in another project creates unwanted dependencies

I have a project ProjectA in which I am keeping utility classes. I want to use this project in multiple solutions so I do not have to copy files, link files and update files every time I make changes in classes of Project.
But there seems to be a problem: if I am referencing ProjectA in ProjectB, the compiled application of ProjectB can not run unless there's a compiled application from ProjectA next to it. So if the output of ProjectB is ProjectB.exe, ProjectB.exe gives an error upon execution if ProjectA.exe is not next to it. Why is that? I just want to use namespaces from ProjectA in ProjectB, I do not need ProjectA to depend on a compiled version of ProjectB.
Can anyone tell me how to reference ProjectA in ProjectB without needing the output of ProjectA to run the output of ProjectB?
You probably need a shared dll.
You have created utility classes in project A out because they are shared all across project A (Application A?), now you have introduced project B (Application B) and as you state it needs to get hold of the code from projectA.dll/exe.
So create a new project in your solution (Ab.Shared.dll maybe:-)) and move your utiilty classes into it. You can now reference that dll from both project A and project B.
Update: Just read about your comment about sucking code out.
The shared dll is the most common way of sharing the code about, but there are other ways. Theoretically you can simply "include" the same *.cs files in both projects and share them that way (use the drop down on the Add existing item dialog and select Add as link) . However in practice it becomes more awkward maintaining this scenario so most people use a shared dll.
Namespaces are not restricted to one assembly - you can use the same namespace across several assemblies if you wish, and one assembly can contain as many namespaces as you like.
If you are referencing a class/type from another assembly, then that assembly must be present (or locatable) when you run the original assembly. If all you are doing is coding then a simple project reference in your solution will do the trick. If you don't have the source code to Project A then you will need it in its compiled form - without it the CLR cannot inspect it and know what it contains.
In that case add the ProjectA compiled dll in your bin folder and add the reference to that dll from your other project. Do not add reference to your ProjectA project.
When you add reference to the project using Visual studio, Add Reference -> Projects, then it requires the project to be compiled and it copies the dll/exe to the other project bin folder.
Open your csproj file in text editor and insert xml:
<Reference Include="AssemblyName.dll">
<HintPath>$(EnvironmentVariable)\bin\AssemblyName.dll</HintPath>
<Private>False</Private>
</Reference>
If I understand correctly, you have code in ProjectA.exe that you want to use in ProjectB.exe, but at run time, you'd like to run ProjectB.exe without requiring the user to have a copy of ProjectA.exe.
This is not possible. When you use a type from another assembly, that assembly is loaded at run time. The type is not copied from ProjectA to ProjectB.
It sounds to me like you should extract the common utility classes into ProjectUtility.dll, and then reference that from both your ProjectA.exe and ProjectB.exe applications.
EDIT: ILMERGE might be the way to go. See Linking statically in C# for more information.

C# solutions : using one "Globals" project for external dll's?

(Sorry for might be a trivial question , I'm coming from Java & Maven , and still haven't wrapped my mind around C# dependencies )
I want to use log4net in all my projects. Since I don't want to add the dll to all the projects , I've created a "Globals" project , add a reference to log4net.dll in it , and referenced from all the other projects to the "Globals" project .
However , I can't seem to access the log4net classes from any other project .
using Globals.log4net;
Doesn't seems to work either .
What am I doing wrong?
If all you did was reference the DLL, then all you have done was get a copy of the DLL with every reference to your Globals project. You are still not using the library.
What I would normally do would create an ILogger interface, implement it using log4net in the Globals project and use that implementation in the other projects (plus a mock implementation for tests).
I'm afraid that's not how it works.
You have to add the DLL to all projects you want to call it from.
If you were only using a couple of functions in the DLL, you could create functions in your Globals project to call through to it.
log4net doesn't 'live' in Globals simply by the reference.
My 1st inclination would be to have all of your projects just reference log4net, it clarifies that there's a dependency there no need to hide it in another project.
However, if you do have common logic shared across your classes you could have a "Global" or "Common" class which includes references to shared libraries. To reference those libraries just add the using of the target namespace.
In other words, no matter if the reference is within the same project or another reference project, the using statement will be the same.
For log4net i believe it should just be:
using log4net;
The other way to add the proper reference would be to type one of the class names somwhere in your code ( Logger ? ) and then invoke the helper menu with "CTRL+." or by simply expanding it, this will have the option to add the proper using statement.
That system won't work. You'll have to add the log4net dll as a reference to all the projects. Or create proxy classes, which is much more work.
Read up on the GAC (Global Assembly Cache), this a central storage for DLLs that are shared across projects... thats where I put my log4net DLL. You can then simply add the reference to it in your .config file forevery project you need to use it in without adding the DLL to the projects themselves.
This is a good place to start: MSDN: Working with the Global Assembly Cache

Categories

Resources