Visual Studio 2012 multiple project template with inter-dependencies - templates

I'm in the process of creating a MVC starterkit for work and I'm having problems creating a multi-project template that doesn't require massive manual modification after creation.
What I have is 4 projects that have some dependencies on each other:
StarterKit.Common - no dependency
StarterKit.DAL - dependency to StarterKit.Common
StarterKit.BL - dependency to StarterKit.Common and StarterKit.DAL
StarterKit.Web - dependency to the other three
I've tried going the route of exporting each project using the Export Template wizard, creating a root .vstemplate file and zipping it all up. Although this works (I can create a new solution based on this template), it has some serious problems.
Firstly, the export replaces the entire namespace of each project with $safeprojectname$, i.e. StarterKit.DAL => $safeprojectname$, StarterKit.Web => $safeprojectname$ etc.
This means that when the new project is created (let's call it XXX), what was previously in the namespace StarterKit.Web now ends up in the XXX namespace and what was previously StarterKit.BL also ends up in the XXX namespace!
This is obviously not going to work.
Secondly, some using statements are not replaced at all. For example using StarterKit.Common; is not replaced in the web project because it doesn't have the correct namespace (which is StarterKit.Web).
Thirdly, I have some .tt scripts that contains using statements I want to replace, but even though I set ReplaceParameters="true" in the project, these are not touched at all.
I also looked into creating a VSIX project, but frankly I don't see how I can use that. To me it looks mostly like a zip utility that creates the .vstemplate for you and renames the .zip to .vsix for me.
What I need to do is:
Package all the projects in a single deploy file available as a "New Project" template in VS
When a newproject is created, replace all "StarterKit" namespace references in .csproj, .cs, .cshtml and .tt files with whatever the user selected as the solution name
Figure out a simple process where I can easily update the templates whenever the base projects change (files added/removed, renamed, content changed etc)
Does anyone have any idea if this is even possible?

Full Disclosure: I am the creator of the below mentioned project.
You can achieve the desired result using the IWizard implementation I created called GlobalParams. It makes the information from the solution template level available to the child templates that also run the wizard by prefixing ALL solution level parameters with the word global and adding them to the parameters of the child template.
If you used GlobalParams with the above multi-project template and the user entered "StarterKit", the following would be true:
StarterKit.Common Could access
$safeprojectname$ = StarterKit.Common
$globalsafeprojectname$ = StarterKit
$globalguid1$ = E8C8A064601844439909D6C33AB90CB3
$globalguid2$ = 020DB5ABF76040C7BDA19EAC54DFE3D8
$globalguid3$ = 8392FB760F754C0AB87778845CC28B6D
$globalguid4$ = 13E07D43F523467587296B2C386DEE50
StarterKit.DAL
$safeprojectname$ = StarterKit.DAL
$globalsafeprojectname$ = StarterKit
$globalguid1$ = E8C8A064601844439909D6C33AB90CB3
$globalguid2$ = 020DB5ABF76040C7BDA19EAC54DFE3D8
$globalguid3$ = 8392FB760F754C0AB87778845CC28B6D
$globalguid4$ = 13E07D43F523467587296B2C386DEE50
StarterKit.BL
$safeprojectname$ = StarterKit.BL
$globalsafeprojectname$ = StarterKit
$globalguid1$ = E8C8A064601844439909D6C33AB90CB3
$globalguid2$ = 020DB5ABF76040C7BDA19EAC54DFE3D8
$globalguid3$ = 8392FB760F754C0AB87778845CC28B6D
$globalguid4$ = 13E07D43F523467587296B2C386DEE50
StarterKit.Web
$safeprojectname$ = StarterKit.Web
$globalsafeprojectname$ = StarterKit
$globalguid1$ = E8C8A064601844439909D6C33AB90CB3
$globalguid2$ = 020DB5ABF76040C7BDA19EAC54DFE3D8
$globalguid3$ = 8392FB760F754C0AB87778845CC28B6D
$globalguid4$ = 13E07D43F523467587296B2C386DEE50
With GlobalParams you have access to 100 Guids with the global prefix that are the same across child templates. So the StarterKit.Common project can be given the value of "$globalguid1$" as the project id with StarterKit.DAL and StarterKit.BL building project references to StarterKit.Common using "$globalsafeprojectname$.Common" as the name of the project being referenced and "$globalguid1$" as the id of the project being referenced. I think you can see how it will work for building the references between the rest of the projects.

I never found an answer to this, so I've chosen another route.
I've created a PowerShell script that I include in a zip file with the solution files. The script renames the solution, projects and classes according to a project name chosen by the user.
The bummer is that this has to be run outside Visual Studio

Related

C# Files not getting added in a custom project template - VS 2017

I am creating a New Project Template in VS2017 based on ASPNET Core Web API project. I have followed steps as outlined here: https://learn.microsoft.com/en-us/visualstudio/ide/how-to-create-project-templates
The zip file contains all the files (C# files).
When the new project is created based on the above project template, none of the C# files are added to the project.
Are there any special steps or settings to include the C# files?
I know this response is late but it may save someone else some other day.
I had this issue as well and i realized the solution was to include the CreateInPlace tag as a child of the TemplateData tag in the .vsTemplate for the project.
Unzip the zip file and update this template file. Add the following line
<CreateInPlace>true</CreateInPlace>
as a child of the TemplateData tag
<TemplateData></TemplateData>

How unit test logic in xamarin forms with a separated console project with F#?

I have a complete new/empty project with xamarin.forms 2.3.4 with F#.
I have a shared project, with a extra module for the logic:
module Db
let openDb() =
printf "Hello"
Then I create a console project, reference the shared project & related libraries, and try to run it:
open Db
[<EntryPoint>]
let main argv =
Db.openDb()
0
Now I getting this error:
../Test/Tests.fs(6,6): Error FS0039: The namespace or module 'Db' is not defined. Maybe you want one of the following: XDB (FS0039) (Test)
I not getting any other error. I try both with xamarin & Visual Studio Mac; and also creating a UI test project (however, I only care for logic testing).
This is an empty form project without anything else.
P.D: I make it to work if a just delete the reference to the shared project and link manually the files. However, I wonder if is possible to cover this scenario...
Is there an EntryPoint file under the file that defines the module?
The location of the file can be changed with alt +up arrow and alt +down arrow(win + visual studio) or Db.fs(in Solution Explorer) is right click -> Move up
F# is readed file from up to down.(See "Projects and Solutions" on this site )
It Maybe that(win10 ,visual studio 2017)
Db.fs is difine module. There is an entry EntryPoint program.fs.
Also, if the namespace and the module name are the same, an error will occur. module name for this project is Bar.

How do you change Qt Creator's OUT_PWD setting in the .pro file

I'm trying to set the OUT_PWD parameter when using Qt Creator. The documentation say's NOT to overwrite this parameter. So, is there another safe way to change this parameter in the .pro file?
The reason I want to modify this directory is to maintain a uniform workspace across all of my developers. At the moment when a person opens a new project, they need to ensure the "build directory" is set correctly in the "project" tab. I'd like to make this a parameter that is set in the .pro file so that all developers are working in the same directory structure.
This is important as I have both Apps and Libs combined in a SUBDIRS type of project and need to ensure the Libs end up in the right place.
Thanks for any help you can provide.
This makes zero sense, because the build folder is meant to be arbitrary, and you're meant to have possibly a multitude of build folders for any given project - depending on how you build the project.
I think that your workflow is broken, and the fix is to the workflow itself, not to project files.
This is important as I have both Apps and Libs combined in a SUBDIRS type of project and need to ensure the Libs end up in the right place.
That's done by adding targets that put the executables/libraries where you want them, not by modifying OUT_PWD.
The solution I used was the following.
Debug:DESTDIR = $$PWD/debug
Debug:OBJECTS_DIR = $$PWD/debug/.obj
Debug:MOC_DIR = $$PWD/debug/.moc
Debug:RCC_DIR = $$PWD/debug/.rcc
Debug:UI_DIR = $$PWD/debug/.ui
Release:DESTDIR = $$PWD/release
Release:OBJECTS_DIR = $$PWD/release/.obj
Release:MOC_DIR = $$PWD/release/.moc
Release:RCC_DIR = $$PWD/release/.rcc
Release:UI_DIR = $$PWD/release/.ui
The build directory is still placed in whatever location is specified by the .pro.user file (which is not something I was concerned with), but at least the lib files are placed in a known location relative to the .pro file and will therefore be uniform across my developers.
I found part of the solution at this link (How to specify different Debug/Release output directories in QMake .pro file), but the main difference is the addition of $$PWD/ to the beginning of the path

Roslyn workspace.OpenSolutionAsync().Projects always empty?

I'm trying to create a self-hosted WebAPI 2.0 project that allows you to open/explore/build .sln solutions through an API.
Here's the code within one of my controllers, that's supposed to return a list of projects given a path to the .sln:
public async Task<IHttpActionResult> GetProjects(string slnPath = "")
{
var workspace = MSBuildWorkspace.Create();
var solution = await workspace.OpenSolutionAsync(slnPath);
var projects = solution.Projects;
}
I would expect projects to hold the projects in the solution, but according to the debugger, solution.Projects and solution.ProjectIds always seem to be empty.
I've tried this with multiple .sln files, all of which I can open in Visual Studio and see that they have projects in them.
I've seen this question, but my project isn't a Visual Studio add in, it's a class library called from a command line application.
This is generally caused by one of a few things, in order of commonality:
You are missing copies of Microsoft.CodeAnalysis.CSharp.Workspaces.dll or Microsoft.CodeAnalysis.VisualBasic.Workspaces.dll. Make sure when you are running your project that those DLLs are next to the main Microsoft.CodeAnalysis.Workspaces.dll.
You're loading solutions with project types we don't support. We should support any project type except the project-less Web Site projects. Class libraries should work just fine.
We have a bug that's causing us to mis-handle your particular project types. If that's the case, file a bug on GitHub.
If you are getting this issue in unit tests but not in your production code, ensure that you have referenced both Microsoft.CodeAnalysis.CSharp.dll and Microsoft.CodeAnalysis.CSharp.Workspaces in your test project.
JYL mentioned it in the comments of the selected answer but I didnt see it right away.

Incremental build in TFS - How do I update AssemblyInfo.cs version only for projects that have changed?

We have a solution in TFS 2012 that contains several projects. I have set up a Continuous Integration build on our build server and have set Clean Workspace = None. I'm using the TFS Versioning template 2.0 to update the AssemblyFileVersion and AssemblyVersions.
When the build is run, each project has its AssemblyInfo.cs file updated with a new version number even though there have been no changes made to the code in some of the projects. Ideally we want the version to change only if there have been changes to the project.
I was considering building each project separately, but we would prefer to be able to simply build the solution. I have read that Clean Workspace = None should prevent the projects from being updated but it doesn't appear to be happening for me since the timestamp on all the dll's are showing as changed after the build.
I am new to setting up a build process, so I'm hoping there is something simple that I'm doing wrong. Any suggestions would be greatly appreciated.
Update:
After checking the suggested link, it appears that I'm doing two things during build that may be causing the issue: 1) web.config file transforms that take place in an "AfterBuild" step in one of my projects and 2) using the version number increment features in the "TFS Versioning" template without opening up the workflow to see how it is checking for changed files. I'll remove both of these and see what happens.
This is a good question and it is possible. I run powershell scripts that use the TFS API to determine what files have changed
You need to get the changesets and shelvesets also, but once you have these you can get the information you want like this:
function Get-ChangesetChanges()
{
[CmdletBinding()]
param ([Parameter(Mandatory=$true)][string]$Changeset,[Parameter(Mandatory=$true)][string]$TFSServer)
[void][Reflection.Assembly]::LoadWithPartialName('Microsoft.TeamFoundation.VersionControl.Client')
[void][Reflection.Assembly]::LoadWithPartialName('Microsoft.TeamFoundation.Client')
$tfs = [Microsoft.TeamFoundation.Client.TeamFoundationServerFactory]::GetServer($TFSServer)
$vcs = $tfs.GetService([Microsoft.TeamFoundation.VersionControl.Client.VersionControlServer])
$vcsChanges = $vcs.GetChangeset($changeset).Changes;
$changes = #();
foreach ($change in $vcsChanges)
{
$changes += $change.Item.ServerItem;
}
$changes;
}