I'm splitting an old project up into it's component parts so that the individual components can be used by several other projects.
There are around 4 stages that are split up into components and 3 master projects which will reference these components.
There's a main class (located in the Shared Project, call it Master class for reference) that is consistent throughout that is shared.
I've setup a shared project and added the references, working fine.
The problem comes when trying to pass a variable using Class A (referenced from Project A's version of Master class) to a method in Component A's version of Master Class, I get compatibility issues.
(Along the lines of cannot implicitly convert MasterClassA to MasterClassA)
I know they're identical and I understand that they are essentially a separate instance of Master class, which is why they're not currently compatible.
I've looked into generics/reflection, changing to a Portable Library Class and seem to be going around in circles.
I know reflection is slow so I'd like to avoid it if possible.
Any guidance on best practice and how to resolve the issue?
Here's a crude diagram of the layout.
In case anyone comes across this, this answer resolved the issue for me;
Referencing shared project in several projects of solution
Essentially we create a class library that references the Shared Project, then reference the new project, not the Shared project.
Related
I've got a problem - project MP_WIN depends on project DLV_WIN!
But now in the project DLV_WIN in one of it's forms i should show a form frmContractPrint that's located in MP_WIN
using (frmContractPrint _frm = new frmContractPrint(wrapper))
{
_frm.ShowDialog();
}
so you understanding that adding in DLV_WIN reference to MP_WIN would cause circular dependency.
The Problem is that the project is so huge that there is absolutely no way to somehow amend the architecture.
can you suggest the fastest way I could resolve this issue and call that form!
There is a serious design flaw in your code. Projects should not have a tight binding both sides. If there is, you should combine the two projects.
Some options:
Create an intermediate project where you put that form (and probably shared other stuff). Include that new project into both existing projects.
Create a utility class that instantiates the frmContractPrint form in the upper project, while the lower depends on the method signature or an interface to interact with.
Lets say I have two projects.
a main project that needs files from the secondary project (lets call this the library)
a project (the library) containing multiple files that I could use in my main project (lets say it has 100 classes available).
Now I could create a C# class library (.dll) and reference it from my main project.
And all the functionality is available.
But what if my main project only needs 25 classes from the total 100 available. For the current situation that is an overhead and in my opinion I would be better of with direct file referencing from the other projects.
What would be the better of those two options (.dll or referencing the source code files in the library) and why?
I would say create a library (dll) and reference that. In that way the library can be used by multiple projects and you will have a single code base maintaining the library.
There is always that specific situation where you might end up in referencing the whole library and only using one class out of it.
The class library is fine and I don't believe only utilizing 25/100 of the classes is really any overhead at all. If you are truly using only 25 of all the classes in the library, then you will need to determine if those 25 class are all related and therefore better suited to be encased in their own project/dll. You can still have a single solution for your class libraries, but have different projects based on function of the classes in each.
I have a set of methods that do some utility work over SQL connection, and until now these have been copied over from project to project. But as time goes on, project numbers have grown and I need to keep these methods in sync in case I find a bug or need to update it.
I have managed to get it to the state that SQL access class is a partial class, one part is specific for project and contains wrappers for a specific database. The second part is the common one and contains methods that are used in all project-specific databases.
The problem is that now I would have the "utility" class copied over 8 projects, with the same content, but in different namespaces. In C/C++ it would have been simple, because I would just have #included the contents of the file wherever needed. What should I do in C#?
Separate out the class so that you can have a complete class containing all of the common code, in a common project. Use a common interface to represent the bits of functionality which will be project-specific, implementing that interface in each project and passing an instance of the interface into the common code where necessary.
As Jon says, a library assembly is a good idea.
There are some situations when an assembly reference doesn't lend it self to the requirements so, if creating a library assembly is not an option, it is possible to use a feature easily overlooked in Visual Studio, adding an existing file as a link.
This would allow you to maintain the common part of the partial class in a file that is available in all your projects.
The only restriction is that a relative path is used to reference the file.
The only problem I have had with this strategy is with the open source Mercurial scc provider. When removing a linked file from a project, the underlying file is deleted. Quite annoying but this may not be an issue for you.
Update: The linked file bug in the VS Mercurial SCC should be fixed in the next release.
How should I divide source files into projects (within one solution) to
be able to use common classes in more relatively independent apps,
avoid lots of dlls needed (preferably all in one file for each application),
keep it fast?
There are working (data processing) classes, User controls, some utility classes and Forms of the application.
You can make a separate assembly by creating a class library, and use that library within other projects within your solution. Just put your reusable classes within a class library project, and add a project reference in your applications to that library.
Each time you separate out code into a separate (reusable) assembly, it does add one extra DLL (the class library project) as a requirement at runtime, but this is very minimal.
There are no real (significant) changes to performance when doing this. It is a very common practice.
You should make Class Library project(s) for each logical unit of classes, then add references to the libraries in each project that uses them.
For example, you could have a Common library that contains basic classes used by everything else, and perhaps a Controls library that contains user controls.
Each logical unit of classes can go in a namespace within the same library or in a separate library; you need to decide which.
It would be a good idea to drop the second requirement of avoiding lots of DLL's. If you put your common code into a single "common" DLL then you need to recompile every time any class is added or modified. This could then give you a terrible versioning problem that is worse than managing lots of DLL's.
You should group your common code, by the functionality they provide, into separate DLL's. So one for data access, one for user controls, one for each type of utility function, etc. Then if you have web service that accesses data you won't need to recompile the service when you add a new user control to a single DLL. Only those apps that depend on the change will need to be recompiled.
You could put the common classes into one assembly (say CommonUtils) and then use namespaces inside for the groupings to indicate how they are split
I've got a question about references between projects in a solution. Most of my previous applications have just had one or two projects in the Solution, but this time I want to divide the application further.
I'm starting a new Solution in Visual Studio 2008 now, and have created several underlying projects to divide the separate parts of my application.
But currently I'm just creating the different projects on a whim, and creating references between them when I need to. Sometimes I end up in a situation where two projects need to reference eachother, but that is not allowed since it would cause a circular dependency.
Are there any rules/tips/patterns I should keep in mind when I create the different projects, and linking them together?
Should I start from the inside, and go out? Having the "core" projects refrence all the outerlying projects, or perhaps go from the outside and in where the independent projects all reference the "core"? Or the third option where I have business in two projects, and they both reference a third project?
Indeed you can't have circular references, but to be honest what would be the benefit of splitting the solution into small project if you had interdependencies between all of them?
Usually before I even open Visual Studio I take a piece of paper and split my problem into logical functional areas. You can draw a Utilities assembly at the top and all the GUI's, web services and other end projects at the bottom. The Utilities project is not going to reference any other project, and the ones at the bottom will not be referenced by anything. Then you think what functionality is common for these, e.g. all GUI's can share a common UI project with common user controls and dialogs, and this UI project will reference the "object model" project, etc. The project at the bottom can only reference what is above them.
Often when it appears that you need a circular reference, you can nicely get round it by defining an interface in the lower level assembly, and providing implementation in the upper level.
Without knowing what are you exactly doing I am afraid that's the only advice I can give you.
It's a bit old-fashioned, but for help in deciding how to split into projects, you could look up "Coupling" and "Cohesion" in wikipedia.
Also, while we sometimes think of these decisions as "style" rather than "substance", we should remember that assembly boundaries do have meaning, both to the compiler and to the runtime. A couple of examples of that...
The C# compiler understands a keyword called "internal". To make the best decisions about factoring into separate projects, you should really understand the power of this.
The JIT compiler in the runtime will never inline a function call that crosses an assembly boundary, which has a performance implication. (The reason is to do with Code Access Security).
There are many more examples, so the decision really does make a difference.
I'll use a Winforms applications as an example. The pattern I have started getting into is this. The solution is called Example.
Example.Entities - This project will contain my business objects and the related heirachy of classes
Example.Dal - I put all business logic and data access logic in this project (namespace) This is the code that loads your business objects and then passes them to another layer.
Example.Gui - I put all my Winforms and GUI utility code here and my 'main' starting entry method. You could also just choose to call this project Example. I still like using the namespace Example.Gui for code separation.
Example.Test - You can put all your test code in this project.
I try to drive code into the Entities if it belongs to one of the business objects or a business object collection.
Gui will reference the Entities and the Dal (Data Access Layer).
Depending on how you write your Dal it may reference your Entities.
Test should reference Entities, Dal, and maybe Gui.
The Entities is its own Assembly dll so that you could use it in other projects. Or return them from a .NET SOAP Service.
The GUI layer should view the internals of the DAL as a blackbox. Your main app should not care how the business objects get loaded or persisted. But you should use your Test project to test your DAL thoroughly.