A pain-free way of debugging a "plug-in" application? - c#

I'm about to start developing a desktop application (WPF) based on a "plugin" architecture, and was going to use MEF (and its DirectoryCatalog) to discover and load plugin assemblies. We're going to be developing many plugins, so it seems sensible to keep them in separate VS solutions rather than bloat the "core" application solution, but having only ever worked on single, standalone solutions, I suspect this is going to make debugging a bit tricky. I'm using VS2013 if that makes a difference.
I'm assuming that I'll still be able to step into a plugin in scenarios where the "core" application calls a method in that plugin? And I'm guessing that once in there, I'll be able to set breakpoints in those source code files that have been "visited"? But what if I want to add a breakpoint to a different source code file - one that hasn't been visited while stepping-through? How can I open that file? In a single solution I could just open it via Solution Explorer, but not (I'm guessing) when it's in a separate assembly.
I'm trying to pre-empt any problems I might have with this multi-solution approach, and wondered if VS had any clever features to simplify some of this stuff. Having separate solutions also means first compiling the plugin solution(s) that I want to test, then compiling and running the "core" application solution. While it's only a couple of extra mouse clicks, are there (again) any VS features that could help here?

This is a common scenario and not tricky at all.
In the project properties of your plug-ins, go to Debug -> Start Action and set Start external program to the executable of your core application.
This way, you only have to compile your core application once (probably using a build script that just builds everything), and debugging a plug-in will start the core application with the debugger attached and you can debug the plug-in (as soon as your core apllication loads the plug-in assembly).
Also keep in mind that you can dettach the debugger from the running application, switch to another instance of Visual Studio with another solution opened, and again attach to your running application. This comes in handy if you e.g. debug your plug-in and want to set or use existing break points in your core application.
As long as Visual Studio is able to find the debugging symbols (the *.pdb files), stepping through the code of e.g. your core application while debugging your plug-in is also no problem.

I see two ways to do this.
The more comfortable option:
1. You can add the external solution to the core solution.
Walkthrough: Adding an existing Visual Studio solution to another solution
By doing this you can organize your solution to reference the code and still keep each plugin solution separate at the same time.
You just reference those plugin solutions from your core solution that you currently want to work on. Also, using this approach you can organize the other solutions just like you would with normal projects and move thembetween virtual solutios folders to your liking until you have the most adequate folder structure.
Quote from the article:
The nice thing about this approach is that not only are all the
projects now in one solution but at any time, you can open the
separate solutions without impacting the "master" solution and vice
versa.
The files in the references solution can be opened and edited just like any other file from your "normal" projects, and of course, you can set breakpoint like in any other code file, too.
This way you can both edityour code and step through it, which I personally find much more convenient than switching and attaching to multiple processes.
2. Add the PDB files.
Put the DLLs with their corresponding PDBs of those plugins you want to debug into a folder and configure your core application to use that folder for the DirectoryCatalog. This enables you to step into the plugin code, but you will not be able to edit them.

#Andrew
Regarding debugging, it shouldn't be an issue as long as you drop the .pdb files with assembly in directory which you are using as DirectoryCatalog.
Regarding building plugin solution before Core- as you have 1 build file for each solution, you should check if you can write msbuild commands in a .bat file to get it executed one after other.

Besides all the above suggestions, another way to debug is to attach your addin solution to the running core process. Attach to Running Processes with the Visual Studio Debugger

Related

Compiling C# Code at Runtime [Update: or Alternatives]

I'm trying to develop an Application in .Net4, that creates a custom Window, inserts custom controls and saves it in a directory. My next challenge is how I can generate/build additional code from my Visual Studio Solution in a WPF .exe Aplication. I need only some classes that will be generated and transformed to a .exe. This classes will give the logic to navigate from one Window to another.
Here is a little diagram that I did for the question:
Things that I have researched:
CSharpCodeProvider: I can pass some classes in a string[] but I don't know how they will work with dependency, or when a error/bug occurs it will be difficult to see where the error is. And finally worst thing is that I can't set a location to build this .exe. It's built in the main Solution/Bin/Debug.
MSBuild: Here I can set the location where I will build the solution, but for this I need an extra Visual Studio Solution. What I'm trying to do is to have inside my Application a Build button that can build like in Visual Studio a .exe program but with custom classes that I will have in my Application.
I don't know if its possible, I was looking for it but I'm a little bit lost. I see in http://www.icsharpcode.net/opensource/sd/ that the have a builder, and they can set the location and build a .exe from the code. The only difference from SharpDevelop is that my controls and Window are customs.
UPDATE:
Maybe what I'm trying to do is better with other tools. Maybe compiling C# in runtime is not he best way. I will appreciate another ways to solve the problem.
What I do is Creating a new extra project for this .exe and must just copy/paste this .exe to each Project location.
But this is not very useful, if every time we must copy/paste this .exe
I just searching or a solution. I made this as a alternative solution but I don't like it so I will continue to investigate for a generation tool or something else.

Difficulty loading references after their rebuild

I'm writing applications and libraries simultaneously, and whenever I update a library it's a bit hard to get it recognized in the consumer application. I have open a separate Visual Studio instance for each library and application. After rebuilding a library I get in the consumer applications the warning/error below. I then either have to remove the reference and add it again. Or I have to clean and build the library solution 3-4 times, for such warning/error to disappear in the consumer app VS solution. Why would doing that 4 times make any difference to doing it 1 or 2 times..?
Would like to understand why this happens and if something can be done to make this work more smoothly?
Not sure if it's relevant but most of my applications I write in VB.NET and libaries in C# (as I'm in progress of changing everything to C#). I also have C# files from the libraries open in the consumer application VS, as it pops up during debugging. I also reference library dlls in the library project /bin/Debug folder, because I'm making a lot of changes at this point of development.
Warning 1 Namespace or type specified in the Imports 'somelibrary'
doesn't contain any public member or cannot be found. Make sure the
namespace or the type is defined and contains at least one public
member. Make sure the imported element name doesn't use any
aliases. 'local path'
..
Error 72 Unable to load referenced library 'path\somelibrary.dll': The
process cannot access the file because it is being used by another
process.
I'm writing applications and libraries simultaneously, and whenever I update a library it's a bit hard to get it recognized in the consumer application. I have open a separate Visual Studio instances for each library and application.
This is the fundamental source of your problem. Visual Studio does not like it when things outside it's control change. You should have a single solution open with all the relevant projects included in it. Then when something changes, all the projects which depend on that project will automatically be rebuilt. (At least, that's the default.)
After rebuilding a library I get in the consumer applications the warning/error below. I then either have to remove the reference and add it again. Or I have to clean and build the library solution 3-4 times, for such warning/error to disappear in the consumer app VS solution. Why would doing that 4 times make any difference to doing it 1 or 2 times..?
I don't think it has anything to do with how many times you clean and rebuild it, but how long it's been since you last made a change - you have to wait long enough for the VS instance building the dll to release the lock on the file, before the VS instance that is using it is able to access it.
When you build a project you lock up the .DLL file in the project you build it from, because that is the version of the assembly that the library instance of visual studio will use - however you are referencing that very same library in another process hence the reason you are seeing the error.
You have two options, keep having two instances and then close the two instances open them again and it will be fine.
What you are better off doing is adding the project itself you are referencing (and are getting the error for) to your solution. Then instead of referencing YourProject/bin/debug/assembly.dll add a reference to the local project via the Projects tab. This will then keep one process referencing the appropriate assemblies that it needs.
For every project in the solution check the project settings -> Compile tab -> advanced compile options... -> target framework(all configurations), see if they are all (for example) .NET framework 4. having different or the wrong framework might cause the problems you're having right now

Solution Output Directory

The project that I'm currently working on is being developed by multiple teams where each team is responsible for different part of the project. They all have set up their own C# projects and solutions with configuration settings specific to their own needs. However, now we need to create another, global solution, which will combine and build all projects into the same output directory.
The problem that I have encountered though, is that I have found only one way to make all projects build into the same output directory - I need to modify configurations for all of them. That is what we would like to avoid. We would prefer that all these projects had no knowledge about this "global" solution. Each team must retain possibility to work just with their own sub-solution.
One possible workaround is to create a special configuration for all projects just for this "global" solution, but that could create extra problems since now you have to constantly sync this configuration settings with the regular one, used by that specific team. Last thing we want to do is to spend hours trying to figure out why something doesn't work when building under global solution just because of some check box that developers have checked in their configuration, but forgot to do so in the global configuration.
So, to simplify, we need some sort of output directory setting or post build event that would only be present when building from that global, all-inclusive solution. Is there any way to achieve this without changing something in projects configurations?
Update 1
Some extra details I guess I need to mention:
We need this global solution to be as close as possible to what the end user gets when he installs our application, since we intend to use it for debugging of the entire application when we need to figure out which part of the application isn't working before sending this bug to the team working on that part.
This means that when building under global solution, the output directory hierarchy should be the same as it would be in Program Files after installation, so that if, for example, we have Program Files/MyApplication/Addins folder which contains all the addins developed by different teams, we need the global solution to copy the binaries from addins projects and place them in the output directory accordingly.
The thing is, the team developing an addin doesn't necessary know that it is an addin and that it should be placed in that folder, so they cannot change their relative output directory to be build/bin/Debug/Addins.
The key here is that team is responsible for a deliverable. That deliverable is a collection of binaries. So the "global" solution ... or "product that uses the deliverables from teams" is interested in ensuring that all of the 'current deliverables' work together. That is, that you have a deliverable from the collaborative effort.
So this begs a few questions. Do the team deliver what they consider to be a 'release'. This may be automatic in the build system. If it builds and all tests pass then publish it.
What you are looking for is a team publishing or promoting a release. The source code is how you got there, the binaries are the result. Each team controls what binaries it considers to be a release (this may be automated by the build system).
Not exactly what you asked, but I hope it is the answer that leads to the right questions to give good results.
One very simple way would be to create the solution. Include all the projects and add a project (or more) to handle the global solution build tasks. The projects in the global solution should then have a reference to the projects they need and then let Visual Studio handle how to get the binaries from each project. They will (under normal circumstances) be copied to the output folder of the build project. So the project added specifically for the global build tasks would have a copy of all the referenced projects
Another way would be to create a global MSBuild script that references the rest of the build scripts. Each project is on it's own a MSBuild script
EDIT
From the comments it would seem that there are two categories of projects. One that needs building and one that does not.
For those that need building reference them as projects in the aggregating project for those that do not require building add them either as references or add the dll as resources.
Using the later change the property of the Build action to None and copy to output directory to Copy if newer
In both cases you now have all dll's in the output directory you can then have a post build action on the aggregating project moving the dlls that should be in a specific folder (ie not in the output folder)
Have a look at the practice of Continuous Integration and the usage of a Build Server with scripted builds. This is an indispensable instrument when developing different parts of an application as a team, and your problems are a great illustration of the reason why.
You've not mentioned if you use a Version Control system. I've found in practise that each developer maintains his/hers/their teams configuration and builds locally on there machine, since you don't check *.suo or *.user files most of the personal configuration only affects the individual team member.
On a completely seperate machine check-out the same code from all repositories and compile the project on the build machine (this can be completely automated). This maintains your build servers independance.
Don't worry about it being a "Solution". You can easily build multiple solutions one after the other.
Since the output path is relative (and probably "bin\Debug") it'll get built wherever you check it out to. If you want all the binaries in the same output folder you could tweak the output path on every configuration to match. Something like "....\bin\Debug" (obviously this affects where the projects get built to on the local machines but it might not matter). That way multiple projects would get built the same target output.
You could also include a seperate setup build on the build server which isn't on each developers local machine to package up the final product.

Orchard: Full Source or Not?

We're going to be using Orchard as a base for a particular client. We're a C# shop running VS2K10. We'll throw it in our version control system as per the norm for our projects.
That said, we'll be creating custom modules based on the needs of our clients. What approach does everyone here recommend?
Get full source from CodePlex and check that in
Download just the Orchard web code (similar to Web Platform Installer)
Problem with #1 is that the code base is rather large, but it will allow us to debug the site locally when developing.
What are the caveats with #2? Lack of debugging?
I'm curious what everyone's approach would be for this. I'm inclined to go with #1, get the full source, throw it in SVN, and build off of that.
Thoughts?
If you are going to develop modules using Visual Studio, just use the full source code. Disk space is cheap.
Caveats with #2 are that it's immensely less comfortable. Why bother?
I use the full source version, but I only check the modules and themes that I'm working on into source control.
I did originally use just the web code, but found myself running into lots of little problems that were much easier to track down when using the full source.
I found that only source controlling the stuff I was working on made updating to later versions of Orchard much easier.
I'm no software engineer, but here is what I would do :
Get the source code.
Add it in your VS solution and source control.
Do NOT reference the project(s).
Add a post-build event on that project to copy the dll and the symbols (for debug) in the folders of the project that would otherwise refer this one.
If it crashed in a class from that project's assembly, you'll be able to specify the source code files since you got the symbols, and since you won't be modifying that project on a regular basis, your VS won't rebuild it every time. You could even unload the project if you want to save some memory, however trivial it might be.

ASP.net/C#: How compile classes in App_Code so that can be run from command line for unit testing?

I have several class files in App_Code in an ASP.net website running in Microsoft Visual Studio 2005 Professional.
In liu of using a full unit test suite I just want to somehow compile those project-wide classses into an .EXE so that I can nightly run unit tests on them.
I do know how to create a separate C# library project consisting of those files and how to include them into my website--but that is not desirable--I don't want to give up the ability to make on-the-fly code changes of those library classes when running the website in the debugger. As far as I know .Net debugger isn't powerful enough to modify code in included libraries with instant auto re-compilation on page re-load.
So, I want my cake and eat it, too:
Command-line unit testing of website class files in App_Code directory
Being able to modify those class files w/o stopping/re-starting the web debugger.
Is it possible to have both?
You should put the code in an altogether separate class library/assembly, then reference it from your web project and the command-line utility. As far as I know, it makes no difference where you modify your code, when stopped in the debugger. Never had problems myself.
Hope that helps.
Your project is under source control, right? Right? In that case, you can use your source control system to include a link to your asp.net project's app_code folder as part of a separate unit testing project. The exact linking mechanism varies by source control platform, but done right it means there's exactly one instance of your App_Code folder in source control that's visible from two different projects. This way, everything stays up to date.
This has the advantage of allowing you to keep easy, uncompiled code right there just like you always have, but still making the code available for testing.

Categories