Multiple applications in single solution - c#

I believe this is possible but unsure how to go around it, I need to create a server/client solution, normally I would create a new solution for the server and a new one for the client however I am looking to do this within a single solution as they would both be using the same custom classes and don't really want the issue of having to change the same file twice.
So the question is can I create multiple exe's within a single solution and what are the steps to achieve this.
I have searched on here but don't fully understand the procedure so if someone can point me in the general right direction it would be great. :)
VS2010 using C Sharp and Windows Forms

Please see this and this previous answer which I gave on cross-platform client server application development, specifically with code-reuse across multiple clients. This is also applicable to your Winforms client server app here.
As many answers are saying, you can structure your solution in order to share code as follows:
Project Structure
Solution
.. Common (Messages, Datacontracts, Utilities)
.. Middleware (References Common, provides common services)
.. .. Server Exe (References Common, Middleware)
.. .. Client Exe (References Common, Middleware)
Top level client-server architecture
Your stack becomes
Clients:
Client has serialization, client side implementations of webservices/middleware and Model-View-Presenter patterns for the view.
Middleware:
Middleware, i.e. shared services and data transport implemetation on server / client desktop can be the same. Alternatively you could call this Services. Any specific services for client only (or server only) should go in separate assemblies and referenced only by the specific exe (client or server). i.e. dont share code that isn't shared!
Messages/DataContracts:
Shared across all clients/server using the techniques I outlined above. In your case these may be common domain objects shared between client and server
Server:
All business logic, DB access and server-side service implementations. For DB Access I'd recommend PetaPoco as an excellent MicroORM.
Development and debugging
Yes, a solution can have more than one exe, simply use set Startup Project by right clicking on Server Exe or Client Exe to debug one or the other.
If you wish to run the client and server together, you can run both from the command line and attach the debugger to both processes.
Best regards,

First, ensure you can see the solution file in the solution explorer:
Go to Tools->Options. Then under Projects and Solutions ensure Always Show Solutions is checked.
Then, in the solution explorer (top right, where your project's files are) right click on your solution (just above your project icon) then click Add->New Project.
In terms of the layout of the solution, you'd have 3 projects, the client project, the server project, and a class library project of shared classes.
Your client and server projects would reference the library project, see: Project Reference (MSDN)
See also: Multi-Project Solutions (MSDN)

You would do it like this:
Have one solution
Add three projects to the solution:
Project A: The server exe
Project B: The client exe
Project C: A class library project containing the classes that projects A and B use.
Make project A and B reference project C

You can right click on solution icon located at the top in the solution explorer and choose add new project option.

Add a new Class Library project to your solution. Put your common code in there.
Add as a many WinForms projects you need to your solution.
Add references to the Class Library project to your winforms projects.

There is nothing special about multiple project within a single solution - VS 2010 supports this fully, see http://msdn.microsoft.com/en-us/library/23x5fk78.aspx .

You can also add the same project to multiple solutions. There is no need to have both the server and client output in a single solution.
In other words, if these are the projects you want to use in both server and client:
Project A: CoreClasses
Project B: Entities
Then simply add them to both solutions:
+ Solution 1: Server
+- Project A: CoreClasses
+- Project B: Entities
+- Project C: ServerSpecific -> output
+ Solution 2: Client
+- Project A: CoreClasses
+- Project B: Entities
+- Project D: ClientSpecific -> output
In your trunk, it would look something like:
/trunk/
/trunk/ProjectA/
/trunk/ProjectB/
/trunk/ProjectC/
/trunk/ProjectD/
/trunk/ClientSolution.sln
/trunk/ServerSolution.sln

Related

How should I structure my VSTS project folders?

I am trying to understand how I should structure my TFS/VSTS Folders and local workspaces/folders/mappings, etc. I am looking for a best practice approach I can follow along.
Currently I have got two projects within my VSTS account:
$/ProjectA
+- Main
+- ProjectA
+- ProjectA
+- ProjectA.sln
$/ProjectB
+- Main
+- ProjectB
+- ProjectB.sln
As suggested by this MSDN link I have created a 'main' folder at the root of the project. So I am able to create branches in case it is needed later.
Please note that ProjectA has an additional folder called ProjectA, which was created by Visual Studio, when using the new project wizard and checked "Add to source control".
Regarding ProjectB: First I have created the solution without adding it to source control. But then later moved the solution into the folder that is locally mapped. And afterwards opened the solution and choose "Add solution to source control".
I have got one workspace, called: "MyWorkspace". The path mappings within this workspace are set as follows:
$/ProjectA ==> C:\Dev\Projects\ProjectA
$/ProjectB ==> C:\Dev\Projects\ProjectB
NB: Both projects have nothing to do with each other.
Questions:
How should I structure my folders within the VSTS project? At which level should the .sln file reside?
How should I structure my local folders and the mappings?
Should I use one workspace containing all project-mappings or one workspace per project? Or should I even have multiple workspaces per project as suggested by some blogs? (sorry cant find the link anymore)
I agree with Flater, This question is completely subjective.
However MSDN provided the suggestions on using the server-side structure and client-side structure, also Branched Folders and Workspaces explained.
Strategies for Solution and Project Structure
The three most common strategies used to structure solution and
project files are:
Single solution. If you work on a small system, create a single solution and place all of your projects within it.
Partitioned solution. If you work on a large system, use multiple solutions to group related projects together. Create solutions to
logically group subsets of projects that a developer would be most
likely to modify as a set, and then create one master solution to
contain all of your projects. This approach reduces the amount of
data that needs to be pulled from source control when you only need
to work on specific projects.
Multiple solutions. If you are working on a very large system that requires dozens of projects or more, use multiple solutions to work
on sub-systems but for dependency mapping and performance reasons do
not create a master solution that contains all projects.
In general you should:
Use a single solution strategy unless the resulting solution is too large to load into Visual Studio.
Use multiple solutions to create specific views on sub-systems of your application.
Use multiple solutions to reduce the time it takes to load a solution and to reduce build time for developers.
Please refer to below links for details:
Strategies for Solution and Project Structure
Structuring Projects and Solutions in Team Foundation Source
Control
In some cases, you can create multiple workspaces to isolate and switch among the changes you are making in different branches.
If you’re using local workspaces, then you can see some performance benefits by switching to using “one branch == one workspace”. Please refer to phkelley's blog for details:
TFS Version ControlUsing multiple workspaces with Visual Studio
You can also reference jessehouwing's answer on how to use the workspace: https://stackoverflow.com/a/48355207/7466674

How to customize class library config settings across projects & clients

Apologies if this has been asked before; after two days of searching I can only find partial answers that don't fully relate to my situation, and are difficult to follow with my lack of experience.
I have a solution that contains four projects:
Class library (containing database connection strings, email server settings, plus lots of other settings)
Web application (web forms)
Web application (MVC)
Web API
Projects 2,3 & 4 all reference the class library, and use the database connection strings, etc, to function. These projects also contain their own additional settings in web.config, bespoke to that project.
Everything works great so far... However, I now need to publish client-specific versions of my solution, e.g. the solution for ClientABC requires different settings for each project than for ClientXYZ. All other aspects remain the same, it is simply the config settings across the four projects that need to change.
From my research, I hit upon something called SlowCheetah which transforms the config files based on the publish profile. That sounded promising, but then I get this problem, where the class library settings aren't pushed into the other projects. I can see bits of useful info in this question, but don't have the experience to apply it to my problem. I'd rather not duplicate the settings into respective project's config file if possible, as that feels messy.
Can anyone please offer me some help as to what's best here? I don't even know if I'm taking the right approach, but am pretty sure I can't be the first ask this?
but then I get this problem, where the class library settings aren't pushed into the other projects
you have to keep in mind that the configuration file is readed by the SturtUp application, your client. Class Library can't run directly, but inside a WebApp or WinApp or ConsoleApp
So, any settings that you put in your ClassLibrary configuration file must be copied in the configuration file of your WebApp.
Generally, I copy some settings from app.config to web.config but, if you search on internet, you can find a method to automate this operation.
I now need to publish client-specific versions of my solution
You can create many configuration profile and use a web.config transformation:
From ToolBar or Build Menu, select Configurazion Manager...
Create all configuration you need for clients
Now you can see different web.configuration files
Now you can specify different configurazion transformation for your ClientABC, ClientXYZ and publish them with specific configuration
EDIT:
So, you can adopt this solution for your Class Library too, or external config file, and include external file in your web.config: External Config

Build same Project as Console and DLL

I've got an C# Project in Visual Studio, which has Console Application as Output Type.
But I also need a Class Library of this project for another solution.
Right now I have to switch the output type every time, but I wonder if it's possible to generate exe and dll at the same build-event?
Is there a post-build-event for this?
To my knowledge there is no possibility to change the output type after compilation. That being said, if would be possible to have two projects like Console and Library in your solution, which would use the same source code files but have different output types. That way you would have different outputs without any duplication of code.
it is generally possible to reference a .net exe assembly as it would be a class-library.
So you can just stick in creating an exe file and reference the exe (sounds strange, but works) in your other project.
This is the dialog for browsing for references. As you see you can select exe files.
But as commented it really depends on what your usecase is.
I don't recommend to ship an exe with an entry point to your customer hoping that the customer does not discover the exe. But what you could do about that is to conditionaly compile your entry point.
For example
class Program {
// This is the entry point of the EXE
public static void Main() {
#if DEBUG
// Start Debug Application
...
#else
// Shipped to client - Entry point disabled
return;
#endif
}
}
If there is a relevant reason to have a shipped exe and a shipped class library, I would refactor your solution like this:
(A) complete application (.sln)
(B) console-application (.csproj) which has a reference to (C)
(C) class library project (.csproj)
With that it is perfectly clear to others that there is an application that uses the library and the library itself.
Console Application is the type of your project. You can not change it.
What you can -and must- do is, carry your logic into a Class Library project and use your class library from any type of project you want.
You should compile your project to become a dll and then use this dll in a console application.
A possibility to achieve what you want is to manually run the msbuild on your post-build event of your project.
See: How do i build a solution programatically in C#?
or Building C# Solution in Release mode using MsBuild.exe
The usual solution for this is using a Solution with two projects:
a Class Library with all the code (which builds into a DLL)
an Console Application referencing the library whose Main just calls some function(s).
For more information, check the MSDN page on Solutions.
Codor suggested manually adding the files to the Console project, but one downside is that build settings are not shared between both versions, so you might get some inconsistency there.
I'm not really sure why people think it's not possible but it actually is.
The easiest way would be renaming the exe to dll Sounds stupid, I know. But it works in many cases. Also, as "Peter I" said a .NET exe can be imported as assembly in other projects. So you might not actually need a dll anyways.
Another way would be using C# command line as stated here: /out (C# Compiler Options)
You can use command command line options in Pre/Post build events Pre-build Event/Post-build Event Command Line Dialog Box
I have a similar requirement and couldn't find any definite answer in this post or anywhere. I currently have a class library and would like to create a console application project without copying any code. Ideally speaking there should be two projects, one for creating a console application and another for creating a class library. And this is what the visual studio also suggests. When I tried to run the class library, I got the below message.
It clearly asks us to add an executable project to the solution and add the reference to the library project.
Below are the steps to do this.
Right click solution -> Add new project -> Console App -> choose name -> ok.
Right click on the console project -> add reference -> In reference manager, click on the projects tab and select the other project(In my case this is the class library project, In case it is not listed just click on browse and select the .csproj file) -> ok.
Now to use the classes in the other project, simple do using LibraryProjectNameSpace
There we are. Bingo!!!!
Also as mentioned in the other answers it is not possible to have the same project generate both .exe and .dll. But you can have the same solution generate these two guys by having two projects. In this way there is no need to switch the output of the project every time.
FYI, I use visual studio 2017

Good practice for working with multiple solutions in Visual C# Express

Background: My team is made up of 3 fairly inexperienced developers. We are developing in-house software for our company. Currently we have a number of smaller and separate solutions. Many of these are interdependent. Currently these depencies are made by referencing the output dll's in the respective release-folder. Updates are pushed around by manually rebuilding dependent solutions.
Example:
Solution A uses features of solution B. The connection is made having Solution A referencing ...\Release\B.dll . Changes to B propagates by building solution B, then building solution A and so forth.
This has worked okay before, but now we are moving from a manual (mind numbing) "version control system" (folder1, folder2, folder2New...) to using a proper one (git).
It seems that versioning the .dll's is not recommended. This means that every time someone wants to build a new version of A, he also needs to build B (and maybe 5 other solutions) in order to have the latest version of B.
I'm thinking that there must be a better way to do this.
I've been looking at combining the relevant solutions into one master solution, but I can't figure out how to do this in Visual C# Express (which we are using).
So at long last the questions:
Is having a master solution that builds everything the way to go?
-- it seems so from MSDN but I can't figure out how to do this in Visual C# Express 2008, which leeds me to
Is this even possible in Visual C# Express? If not, what is a
good way of managing the problem?
Edit Thanks to all for the great suggestions below. Here's a summary of what I ended up doing.
In short the answers to the questions are: "Yes" and "Sort of, but mostly yes". I implemented as follows: In order to get an idea of the dependencies, I did as suggested below, and drew a map of the binary products, with an arrow pointing from the dll's or exe's name to all of its dependencies.
For each project, I opened its corresponding solution (since at first there was one solution pr project). I then added the projectfile of each dependency in the tree structure revealed in the graph (by right-clicking the solution in solution explorer), so that also dependecies's dependencies and so forth were included. Then I removed the old references (pointing directly to the .dlls) and added references to the projects instead.
The important result is:
When a solution of a project is built, all it's dependencies are built with it, so that when deploying, you know that all the build products are automatically of the latest version.
I would create a new solution and add all of the projects that relate to each other to it. You can group the projects from each of the original solutions by putting them in different solution folders within the new solution. This way, when you build a project, all of the projects it depends upon will also get built. It also means that all of your projects will be built using the same configuration (i.e. Release or Debug). This means that all of your projects can be built in Debug, not just the top one in the dependency tree while everything below it is a Release assembly. Makes debugging much easier.
I have Visual C# Express 2010 and when I create a new project, it automatically creates a default solution. If it's visible, then you can right-click on the solution and choose Add>Existing Project.
If the solution is not visible, (I seem to remember this problem in C# Express 2005/8), then you can add an existing project via File>Add>Existing Project. The solution should be visible now.
In terms of speration, what I usually do is this:
Everything that must be built together should be in one solution, and these should be projects and not DLL's. I try to live by The Joel List, where you should be able to build your project in one step. If it is one deployable unit, then there should be one solution. All of my projects are built on a build server before they can be deployed, so everything should be in the solution that needs to be built.
Guys sometimes put the WCF services project and the clients in the same project for easy debugging, but it depends on whether you want to deploy client and server independently. Usually for bigger projects I separate them.
Lastly there's one exception. We have a central common library that is used by different teams. If it's included in different solutions, and one team changes something, we end up breaking the other team's builds. In this case, we create a single solution that has all of the library projects. These get built to DLL's that we store the versions of. We treat these as a framework that the other solutions can use. E.g. Team A is using CommonLibrary 1.1 and Team B is using CommonLibrary 1.2.
You need to think of Solutions as just "groupings of projects" - the projects are what are actually "built", not the "solution" (well, that's not entirely true, the solution is turned into a "metaproject" that references the contained projects, but its close enough to the truth)
If you have interdependencies between solutions, I would suggest drawing all the projects on a big whiteboard, then draw arrows representing the dependencies from project to project. Once you've done this, you'll be able to see at a glance what the appropriate "groupings of projects" make sense. Those become your solution files.
For example, if you have projects A, B, ..., F, where:
A depends on B
B depends on C
D depends on C
E depends on F
One possible split here would be solution 1 with projects A, B, C, D and solution 2 with projects E, F.
I would come up with a common area to push all dlls. My company uses the "R" drive, which is just a LOCAL (not network so no one can touch another persons folder) mapped folder everyone has. Each solution will build to this. Right click a project, properties->build and change the output. Or you can add a post build command to push the dll there. After that, have all of your projects reference this location.
Once this is done and everything is pointing at the same place, you can even add different combinations of projects to different solutions. If a developer only wants the ui projects, they can open a special "ui" solution that is a subset of the whole.
Here is a post build event that I use in my project properties->build events
rem when building on local workstation copy dll to local R:\
if '$(BuildingInsideVisualStudio)' (
xcopy $(TargetDir)$(TargetName).* R:\Extranet\$(TargetName)\1.0\ /Y
)
rem if "Enterprise" build then copy dll to Corp R:\ drive and to Build Machine R:\
if '$(Reason)' == 'Manual' (
xcopy $(TargetDir)$(TargetName).* \\folder\$(TargetName)\1.0\ /Y
xcopy $(TargetDir)$(TargetName).* R:\Extranet\$(TargetName)\1.0\ /Y
)

Sharing code between 2 projects without a dll

How can I have code-sharing between two projects without making a dll?
The issue is: I have a tool that syncs users & groups from LDAP to a database.
Now the tool is a windows service, but testing it as such is very difficult and time consuming.
Which is why I made a console application where I can test the LDAP syncing, and then just copy the respective sourcecode-files over to the service project.
But... keeping the common files in sync is a bit of a problem.
I don't want to make a dll, because this probably creates me a problem with
the 3rd project, a windows installer (for the service) where I have to use ExecutingAssembly path...
Is there a way to share the code without making a separate dll?
Automagic statical linking, so to say ?
How about adding a file as a link.
In Visual Studio right click on your console test app project -> select add existing file -> in the file add dialog navigate to files in your actual windows service project -> select the files you want to share -> and on add button select add as link option.
You can add a file to a project as a link. On the Add Existing Item dialogue the Add button has a drop down on its right. Use this to select "Add as Link":
Put the file as a solution item and add as a link to each project.
How about hand-modify the project files to point to the same source file?
Another option - put both projects in the same folder. Add a class to one, then in the other project add existing class and point to the class just created.
You could:
maintain the shared code in a separate project that produces a DLL and then use a tool such as ILMerge to turn the DLL & EXE into one assembly.
share the source-files between multiple projects, either by tweakiing your project files or doing something funky with your source-tree layout.
All that said, the best approach would be to bite the bullet and store the shared code in a shared assembly (DLL). What happens when you decide to, for example, expose this code via a WCF service? It starts getting more complicated then as you have 3 places that reference the same code files. Don't just think about what makes your life easiest now, think about what'll make your life (and that of anyone else who has to maintain the code) easier in the future as well! =)
Necromancing - As per Visual Studio 2017:
You can create a shared project, and then reference the shared project in another project.
It will use the framework-version and libraries from the project you reference the shared-project from. You can also use the same shared project in multiple projects, provided you get no conflict.
This is basically statical linking on a source-code level.
This also works with HTML&JavaScript-files (specifically, it works with publishing), but with HTML & JS files, you will run into problems while debugging...
It's under "Classical Windows Desktop", but you can also use it for .NET Core etc.
If you want to share functionality, you should use a DLL or similar.
Since what you want to share is the source, what you are essentially sharing is file sharing. So you can do that by making your projects reference external sources or you can have your source control do this for you.
If you are using Visual SourceSafe, you can make a link between two folders. VSS will make sure that they are treated as the same file.
I'm going to describe the setup we use to manage and test our Windows Service projects. While this doesn't answer the question of "sharing code without a DLL" (Unmesh's answer takes care of that), I think the OP probably doesn't realize how easy this is with a DLL. In any case, I'm hoping it will help someone.
Create a solution, LDAPSync. Create three projects in this solution:
LDAPSyncLib
LDAPSyncSvc
LDAPSyncTest
LDAPSyncLib is a DLL project that contains all of your business logic and main functionality.
LDAPSyncSvc is a Windows Service project that contains two classes, a service controller class that inherits from ServiceBase, and an Installer class for your service. This project has a "project reference" to LDAPSyncLib.
LDAPSyncTest is either a GUI application (WinForms, WCF, etc.) or a console application, depending on your needs. This project also has a "project reference" to LDAPSyncLib. Its sole purpose is to provide some interface which allows you to easily make the required calls into your business logic for testing purposes. In Visual Studio, set this as your "StartUp Project".
Now, when you run in debug via Visual Studio you will get a nice little GUI or command window that you can use to manually make test calls. When you install it as a Windows Service, the LDAPSyncSvc project's controller class will take over and handle all of the necessary service requests (start, stop, pause, etc.)
We have around 30 in-house Windows Service projects that we've been continuously managing, developing and testing for over a decade and this workflow has proved invaluable in quickly finding and fixing bugs when they arise. Best of luck with your project and I hope this helps some future Googlers.

Categories

Resources