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

(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

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.

Global using directive in c#

I'd like to create a namespace in c# that can be found in any project. Not just the one that it is located in. like the system namespace. Is that possible and if yes I'd like to know how.
I already googled and didn't find anything
Classes in the System namespace are part of the Base Class Library (BCL) that gets included as part of the .NET Runtime. The only way for you to have your class be as globally accessible as, say, the System.String class, would be to convince Microsoft to add your class into their BCL. That is rare, but not unheard of. The IObservable<> interface is an example of a type that was added that way.
However, there are tons of classes that people are using every day without having them added to the BCL. If you're willing to accept one additional step for people to take with their projects, in order to leverage your project, you can publish your project's output as a Nuget package. Then people only need to add your Nuget package (referenced by its package name), and they'll have access to the public API defined by the types in your DLLs.
Consumers of your package will still need to reference the namespaces of the types they want to use, either explicitly or via a using directive. In C#, a "global using directive" only makes the namespace globally available within the project that the directive is found in.
If you only want your types to be accessible from other projects found in the same solution, Nuget isn't necessary: you can add a project reference.
There are a lot of nuances I'm glossing over (i.e. differences between namespaces and DLLs and packages), but which it would be helpful for you to read about.
One of solution:
You need to create library(DLL) and refernce it in projects.
If you using visual studio 201x you can create project with type class library.
The library namespaces can be found use like this ´using MyNamespace;´
example of class in library:
adding refernce to project:
example of using your own class library:

Use references from attached DLL file

I have created a DLL that contains the reference to Microsoft.Azure.Devices (and some other references).
I'd like to be able to just use this DLL in other projects without the need to reference Microsoft.Azure.Devices each time. Is it possible?
Currently, in order to use any function of Microsoft.Azure.Devices I have to reference it in my new project, which isn't a good solution I think - I'd like my DLL to be a "complete" reference - I just want to use the abstraction layer that I created without caring what is inside (what references are used).
That sounds like you want to use some kind of DLL weaving. That will merge all external referenced assemblies and your assembly into a new one.
There are multiple frameworks to achieve this. I personally have used these two:
IL Merge
Costura Fody
From a usage point of view fody was very easy to use. You basically reference it using Nuget (see https://www.nuget.org/packages/Costura.Fody/) That's pretty much it. It will pack all your references into one assembly.
You can find more information on the Git page https://github.com/Fody/Costura
The only limitation of this approach is that you can not use that with signed assemblies I think.

Converting WebService into DLL

I have one windows service project. I want to convert that web service project into DLL. As a class library I can simply reuse those methods just by referencing that DLL.
I just want to know is there any simple way to do it or I have to manually create one class library project and reuse my code.
You can reference exe in other projects same as dll.
But moving this to separate class library is the best idea.
Just Click on the class library with the service code and select build. it will create a DLL file in your Debug folder in your project bin directory. You can use that DLL file anywhere.Hope this helps..
Just copy your code to class library project and built it. It will create .dll and you can easly use it by adding reference to your project. I think that would be a simplest approach
After searching and asking questions on ASP forums proper way of doing this is to manually reuse code.

C# project reference's question

I have a c# solution and its composed of numerous projects.
I have a project that is my baseassemblies that holds all common information that other projects use. All of the other projects have references to baseassemblies.
I added a dll reference in my baseassemblies however all of the other projects cant see it.
How can I make it so that the other projects can see the DLL that baseassemblies is referencing? I dont want to have to add the DLL to all of the projects since that defeats the purpose of my baseassemblies project.
The correct approach is for your other assemblies NOT to need a reference to that other DLL. The way to correctly do that, is to not have your base assemblies expose any of the types that are within that DLL. Wrap all the functionality that you need in the base assemblies, and make sure that whoever consumes your base assemblies, needs NO knowledge of the underlying dll's base assemblies is using. Otherwise, each project that will reference your base assemblies, if they need to use something that's contained in that dll, they'll have to reference it.
There are no transitive references in .NET. If an assembly needs to reference another it must do so directly, it cannot "inherit" that reference from another reference.
Note, a project only needs to reference assemblies it directly uses types from. If A uses B, and B uses C, but A does not directly use C, then A only needs to reference B directly (the loader will handle B referencing C).
In short you can't do it. You need to add a reference to the DLL containing the code you are trying to use otherwise it won't be able to see it.
My suggestion would be to create a layer in your 'BaseAssemblies' project which you can access from your application which essentially creates a tiered architecture.
example
Application Layer - Uses IDataClass
Business Logic Layer - Defines IDataClass
Data Access Layer - MyRawDataClass (implements IDataClass)
From the example, the application layer only needs a reference to the BAL to be able to interact with the DAL.
You can have your BaseAssemblies export Interfaces that have to be implemented by your "other" dll. Additionally, your BaseAssemblies need some "class factory" functionality for those classes.
Other posters are correct: you can't do it. This is, IMHO, pathetic on the part of Visual Studio. "make" handled this clean as pie 20 years ago...
There are instances where your project refers A which in turn refers B but when you build, B isn't always there in the BIN folder and you only realize this when the code is running. There is a related SO Question HERE. People have solved it in bizarre ways, but I specifically liked the solution by John Hunter. This SO thread also discusses a solution where you use build events to achieve the desired results.

Categories

Resources