Inherit dependencies among projects - c#

Due to an architecture requirement, I would have to have all the 3rd party dependencies centralized in a single project. Then, the remaining projects in the solution would have this project referenced as a dependency to inheriting all of these dependencies in order to avoid having them duplicated along the solution.
I'm wondering if that's possible even if I have to make some tricky adjustments to make it work.
Any suggestion will be much appreciated.
Thanks in advance!

If you reference a project, you are not necessarily referencing it's dependencies.
So, say I have Project A that references 3rdPartyLib.dll. when I reference ProjectA.dll, I'm not referencing 3rdPartyLib.dll.
One way to do it would be to write all of the logic that uses 3rdPartylib.dll in Project A, and essentially use it as an abstraction layer. Then reference projectA.dll and call that logic, and the calling assembly would have no knowledge of 3rdPartyLib.dll

Related

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.

Referenced assembly does not have a strong name c#

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?

Only one project accessible where projects share a namespace

I have a solution which contains say, DataAccess and DataAccessImplementation
DataAccess contains: IFooAccess and other Interfaces
DataAccessImplementation contains: FooAccess which implements IFooAccess, along with lots of other classes that do the same.
Now, both of these projects are in the same Namespace.. 'foo.DataAccess'.
The problem I've got is, in my project that references these projects, only one of these two projects is going into the bin folder at a time when I build and only it's interfaces are available in my code. If I include a reference to DataAccess and DataAccessImplementation, only DataAccess will show for example.
DataAccessImplementation won't go in until I unreference DataAccess, but as soon as I reference it again, the only classes I can find are that of the DataAccess project.
Do these projects need to be in seperate namespaces? Why are the two projects not being added?
Usually no they don't have to be - but it isn't best practice to keep them in one namespace either. To be clear (for ourselves and other developers) we separate them according to their focus or intent. For instance:
com.yournamespace.DataAccess
and
com.yournamespace.DataModels
These will be two separate projects. In this example I've replaced your 'DataAccessImplementation' with DataModels because the distinction isn't clear.
The problem I was having wasn't actually due to the namespaces, it was instead the assembly name that was the same. After changing the names to those more appropriate, it worked fine.

Class Library - References - Reusability with Copy Local?

I have a class library project, lets call it CoreLib.
CoreLib has two references to 3rd party DLL files 1.dll and 2.dll
Because I love reusability so much, I want to be able to use CoreLib in as many places as possible/needed.
So if I had a project called BigProjectA and another project called BigProjectB and they needed to leverage the functionality provided by CoreLib, all I would have to do is add a reference to CoreLib in those projects (BigProjectA and BigProjectB).
That is fine, except when I go to copy over my output folder (bin directory) to another person's computer, I can't guarantee that they have 1.dll and 2.dll on their machines.
For that, I just set Copy Local to True for 1.dll and 2.dll references in the CoreLib project.
When building the CoreLib project I can see 1.dll, 2.dll, and CoreLib.dll files. That is PERFECT!
But in the projects referencing CoreLib, only CoreLib.dll is copied over, not 1.dll and 2.dll.
Am I missing something? Copy Local set to True, but only copies for the CoreLib project. So even though they are in the same solution, and I'm adding CoreLib as a project reference to the other projects, I still dont see 1.dll and 2.dll copying out to the other bin/Debug, bin/Release folders of the other projects (BigProjectA and BigProjectB).
Is there an easy solution?
The easy solution is to either:
reference 1.DLL and 2.DLL in projects which have a binary reference to CoreData.DLL
Add CoreData as a project reference to BigProjectA and BigProjectB instead of as a binary reference
In the first scenario, CoreData's dependencies are not automatically output by the compiler. If the CoreData project is added to the solution, its dependencies will be output. Hence, to use CoreData as a binary reference, you must also reference its dependencies.
There is nothing wrong. In projects BigProjectA and BigProjectB you have a references to only CoreLib, so they "care" about coping only it, cause they have no any clue about it's dependencies. What you can do to resolve these kind of issue, is to add for example PostBuildVEent in your BigProject.. to copy also CoreLib dependencies.
Or add reference to CoreLib project, if you can.
Another solution, is to consider DI like a technique to avoid strong coupling of references. So, if in BigProjectA or B you don't care about functionality provided by 3rd party libraries in CoreLib, for you should be enough to just copy CoreLib.
Good answers guys....but I actually just ended up using ILMerge. Seemed safer/less annoying.
Thank you though

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