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.
Related
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
I have been given a folder than contains many solutions in subfolders along with their code. Each solution builds a PrinterDriver.dll. What I am trying to do is create a master solution that I can add all the projects into and then they will all compile every time.
I cannot at the moment do this, when I add each to the master I get an alert telling me that a project of that name already exists. what is the best way to do this?
I'd urge you not to create a master solution containing projects with the same name, that will end up a mess... You'll have to change assembly names and namespaces and as you've found you end up with dozens of namespace ambiguity errors.
all the projects ... will all compile every time
If the aim is just to compile all the projects at once, every time, then simply write a MSBUILD script that uses all the project files to compile outputs.
Eg: Compiling a .vbproj or .csproj project file without Visual Studio
If you do want a master solution it will require surgery. One way would be to create interfaces (or abstract classes) that reflect the method signatures of each class in every project and using IoC load different implementation classes depending on the target.
Warning: Be wary about changing namespaces, while prefixing namespaces with a unique name may sound simple. You have to be aware of the impact especially on code library's (like Printer.DLL) that other projects reference.
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.
Say I have foo.cs and bar.cs. if I create two seperate projects for each source file and compile them to two DLLs, I have no problem in importing and using them in other projects.
What should I do if I want an output of single DLL?(with keeping separate source files) Can a DLL file have two namespaces? if not, How can I place contents of foo and bar into single namespace? (I can edit them)
if I create two seperate projects
Create one project with both files in it to produce one DLL as output. The namespaces can be anything you'd like, though convention suggests that classes within a project share a common root namespace.
You only have to add both files to the same Project.
Can a DLL file have two namespaces?
Yes. And conversely one namespace can be used in multiple DLLs.
See ILMerge.
Microsoft says:
ILMerge is a utility that can be used to merge multiple .NET assemblies into a single assembly. It is freely available for use from the Tools & Utilities page at the Microsoft .NET Framework Developer Center.
The namespaces are completely independent from the source files and projects. You can have several namespaces in one project or even in one file as well as one namespace for several projects. And of cause you can have several source files in one project (you almost always have many source files per project unless it's a "Hello World"-project)
You can change the default namespace given to new source files in the project properties in the "Application" tab, field "Default namespace". You can also create new folders and subfolders in your project. The name of these folders is automatically added to the default namespace of new source files created within these folders (separated by dots .). And of cause you can always edit the namespace-statements manually. You add or remove and nest namespace statements.
You can also have several projects in one solution. You can even mix projects of different types and languages (e.g. VB and C#) within one solution. Every project usually generates one assembly (dll or exe). It makes no difference whether the projects are within the same solution or not from the technical perspective. It's only a matter of organization.
See:
MSDN: Names of Namespaces
MSDN: Namespace Naming Guidelines
SO Question: namespace naming conventions.
Example of a complex solution:
C# namespaces are quite open.
Yes, you can have several namespaces in one library.
But also: you can add things into an existing namepace. For example: you could add extention methods into the System.Linq namespace, so that you only have to include the dll without requiring additional includes.
You can have multiple child namespaces within a single project. It might be better practice to at least give the project (and, once compiled, the DLL) an overarching namespace, though.
If you only need to merge a single class in these files you can use partial classes
But they have to be in the same namespace anyway.
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.