This process will significantly decrease development time and coding errors. Since we use Unity for IoC and DI, the add-in also registers each interface created with its respective concrete class. We've effectively been able to eliminate the "class does not have a default constructor" error, which was a huge bonus.
It turns out creating an add-in is pretty easy, but getting it to do anything complex is a bit trickier. Below are some pointers on creating an add-in so hopefully I don't make the same mistakes next time.
1: (Solution2)_applicationObject.Solution
That little guy right there will get you the Solution (which seems a bit obvious now).
1: private IEnumerable<Project> GetProjects(List<string> projectNames)
2: {
3: var projects = new List<Project>();
4:
5: // get the projects from the root (solution) object
6: var solutionProjects = _applicationObject.Solution.Projects;
7:
8: // get the enumerator from the projects from the root (solution) object
9: var enumerator = solutionProjects.GetEnumerator();
10: // iterate the projects
11: while (enumerator.MoveNext())
12: {
13: var project = (Project)enumerator.Current;
14:
15: if (project == null)
16: {
17: continue;
18: }
19:
20: // check whether the project is a solution folder
21: if (project.Kind == ProjectKinds.vsProjectKindSolutionFolder)
22: {
23: // if the project is a solution folder, get the projects from the solution folder
24: projects.AddRange(GetSolutionFolderProjects(project, projectNames));
25: }
26: else if (projectNames.Contains(project.Name))
27: {
28: // if the project isn't a solution folder, add it to the results
29: projects.Add(project);
30: }
31: }
32:
33: return projects;
34: }
That beauty will get the projects at the root of the solution. You'll notice on line 24 I'm calling another method named GetSolutionFolderProjects. That's used in case your solution uses solution folder for easier visible navigation (like ours does). Here's that method:
1: private IEnumerable<Project> GetSolutionFolderProjects(Project solutionFolder, List<string> projectNames)
2: {
3: var list = new List<Project>();
4:
5: // iterate the project items in the solution folder (each project item should either be another solution folder or a project
6: for (var i = 1; i <= solutionFolder.ProjectItems.Count; i++)
7: {
8: var subProject = solutionFolder.ProjectItems.Item(i).SubProject;
9: if (subProject == null)
10: {
11: continue;
12: }
13:
14: // check whether the project is a solution folder
15: if (subProject.Kind == ProjectKinds.vsProjectKindSolutionFolder)
16: {
17: // if the project is a solution folder, get the projects from the solution folder
18: list.AddRange(GetSolutionFolderProjects(subProject, projectNames));
19: }
20: else if (projectNames.Contains(subProject.Name))
21: {
22: // if the project isn't a solution folder, add it to the results
23: list.Add(subProject);
24: }
25: }
26:
27: return list;
28: }
You'll notice on line 18 I'm calling another method named GetSolutionFolderProjects... that's a little recursion joke. If you didn't get it, remember this: in order to understand recursion, you must first understand recursion.
I'm going to post more about this later, but I've been meaning to write this post for over a month and just haven't made the time. This is a start.