I thought this would be dead simple to create a class library as Mydomain.Common
Then use this class library in my other projects libraries
MyDomain.OtherA
MyDomain.OtherB
I wan to use Mydomain.Common class library in both projects.
But I also want to use Mydomain.OtherA in Mydomain.OtherB project.
When I add the references and try to build the solution I get the error saying "eferenced assembly does not have a strong name".
I did read on answer on here but I couldn't make sense of it.
How can I achieve this?
I know that in many projects we use this approach to install nuget package in multiple projects and those projects also references another common project.
For example EF, Autofac, AutoMapper.
Is this not possible? Do I really need to sign the dll to use it in this scenario?
Related
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.
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:
I created a class library project using C# and .Net.
In this project I used two external dependencies(to be more specific: Microsoft.Win32.Registry(4.6.0) and System.Data.SqlClient(4.7.0) Nuget packages).
After I build this project, I can see the generated DLL file under /bin/debug folder.
Now I want to import this generated DLL in another project and consume its methods. Once imported and I run this project, it complains about not being able to find those two external dependencies I had in class library project.
As a temporary fix, I can import these two missing references in this project and it will work fine and as expected. But this is not what I want(and I guess is not a clean solution as well).
I want to know why the dependencies of class library project is not reflected in generated dll file? And is there any way to fix this?
Many thanks for your help.
If your class library is in the same solution or source control repository as the app that's using it, you should use a project-to-project reference, rather than referencing the assembly directly. As the docs say, this way it automatically detects changes to the class library when you compile the app, but what the docs didn't say is that dependencies flow though as well.
Otherwise, as Lance Li wrote, you should create a NuGet package from your class library. Unfortunately there's a bit of a barrier to get started. Creating the package is easy, but then you need to publish the nupkg file somewhere. For early development (before the package is ready to be shared), the easiest option is to use a local file feed. You'll then need a nuget.config in the app that will use the package to add that local feed as a source, then you can install the package in your consuming project, which will bring dependencies.
As you can see, for development, this is slow and difficult because if your consuming app finds a bug in your package, or if you're trying to develop a new feature in both the consuming app and class library at the same time, it means every time you make code changes to class library, you need to increment the version number, pack a package, publish the package, then update the package version in the consuming project. It's far, far easier to use a ProjectReference which lets you simply edit code, compile, run. Nothing else to think about.
See this, the way you reference that assembly is not a recommended way when both the projects are in same machine.
You're using the file reference(Add reference => browse...). And that's why you have to import these two missing references in this project manually.
So I suggest you add the project reference, if both the two projects are in same solution, you can right-click current project=>add reference=>project tab find that assembly you need.(instead of browsing...)
If the referenced project is not in same solution. Right-click solution in solution explorer=>add existing project to import it. Then add project reference.
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.
(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