Does Visual Studio 2017 work with Code Contracts? - c#

I just installed the newly released Visual Studio 2017 Enterprise (RC). I'm having trouble getting it to work with Code Contracts, however. I have no problem using Code Contracts with Visual Studio 2015. Am I missing something?

As others have noted, Microsoft hasn't prioritized Code Contracts and its long-term support remains unclear (though there has been some ongoing discussion about language-level integration via Roslyn).
As of March 11th, 2017, however, community contributor Yaakov has, at least, updated the source code to include the Visual Studio 2017 build targets (thank you!). This version provides support for both static checking during compilation, as well as run-time validation using CCRewrite.
Note: This build does not provide configuration support via the project's properties pane. As such, code contracts will need to be configured by manually adding the appropriate properties to the csproj file. See #crimbo's answer below for a comprehensive list of properties.
Unfortunately, while these updates have been merged into the master code branch, they are neither reflected in Marketplace distribution or the official NuGet Package. As such, you need to download and compile the source code from the repository (which is easy; just use the supplied BuildCC.bat file).
Important: The static analysis for Code Contracts has a hard-coded dependency on .NET 3.5, which is no longer installed by default in either Windows 10 or Visual Studio 2017. As such, you'll want to ensure this "feature" is enabled (or download it separately); otherwise, you'll get a compile-time error.
Alternatively, as of June 15th, 2017—and later updated on February 6th, 2018—contributor Igor Bek has included this update in his NuGet Package, so the simplest approach is to just add CodeContracts.MSBuild to your packages.config via:
Install-Package CodeContracts.MSBuild -Version 1.12.0
Background: Igor Bek first put this package together as a proof-of-concept for the Code Contracts team, and it was later the basis for the official NuGet package (in v1.10.10126.2). Since Microsoft hasn't updated the official NuGet package, his is now the most up-to-date.
Given the current state of support, I wouldn't encourage people to adopt Code Contracts for new projects, but this should provide backward compatibility for developers who have already invested into Code Contracts for existing .NET Framework projects.

At this time of writing there are no contract definitions for VS2017, but you can get around it with the following if using Nuget package DotNet.Contracts:
Navigate to the CodeContracts nuget package directory (DotNet.Contracts.1.10.20606.1\MsBuild)
Copy the v14.0 folder
Rename it to v15.0
Everything should build as expected.

There is currently no version of Code Contracts for .NET which supports Visual Studio 2017. However the issue can be remedied, if you copy the following target file
C:\Program Files (x86)\MSBuild\4.0\Microsoft.Common.Targets\ImportAfter\CodeContractsAfter.targets
to the ImportAfter location of your VS2017 MSBuild:
C:\Program Files (x86)\Microsoft Visual Studio\2017\#YourVS2017Product#\MSBuild\15.0\Microsoft.Common.targets\ImportAfter
Note: Replace #YourVS2017Product# with your VS2017 product name in the above path, e.g. Community.
This will allow you to build with Code Contracts in VS2017, but will not solve the issue of the CC tab not showing in the Project Settings. For that you will still need to switch to VS2015.

The reasons that code contracts don't work in VS 2017 are:
Code contracts MSBuild files aren't Imported in the VS 2017 tree of msbuild files (easy to fix)
Code contracts configuration UI isn't present in VS 2017 project properties (easily fixed by include CodeContracts msbuild properties)
Certainly questions about the future of CodeContracts are valid, but you can implement the following to enable existing projects that use CodeContracts to build in VS 2017:
Add the contents of C:\Program Files (x86)\MSBuild\14.0\Microsoft.Common.Targets\ImportAfter\CodeContractsAfter.targets to your csproj files (either directly or indirectly via an import). The most basic approach is to add this to your csproj file:
<PropertyGroup>
<CodeContractsInstallDir Condition="'$(CodeContractsInstallDir)'==''">C:\Program Files (x86)\Microsoft\Contracts\</CodeContractsInstallDir>
</PropertyGroup>
<Import Condition="'$(CodeContractsImported)' != 'true' AND '$(DontImportCodeContracts)' != 'true'" Project="$(CodeContractsInstallDir)MsBuild\v$(VisualStudioVersion)\Microsoft.CodeContracts.targets" />
Note that the first PropertyGroup shouldn't be necessary if CodeContracts is installed, b/c CodeContractsInstallDir should be specified as an environment variable. In that case, you can get away by just adding
<Import Condition="'$(CodeContractsImported)' != 'true' AND '$(DontImportCodeContracts)' != 'true'" Project="$(CodeContractsInstallDir)MsBuild\v$(VisualStudioVersion)\Microsoft.CodeContracts.targets" />
to your *.csproj files.
Specify all the CodeContracts properties in your *.csproj file (directly or indirectly via Import). Eg:
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<!-- Code Contracts settings -->
<PropertyGroup>
<CodeContractsAssemblyMode>1</CodeContractsAssemblyMode>
<CodeContractsEnableRuntimeChecking>True</CodeContractsEnableRuntimeChecking>
<CodeContractsRuntimeOnlyPublicSurface>False</CodeContractsRuntimeOnlyPublicSurface>
<CodeContractsRuntimeThrowOnFailure>True</CodeContractsRuntimeThrowOnFailure>
<CodeContractsRuntimeCallSiteRequires>False</CodeContractsRuntimeCallSiteRequires>
<CodeContractsRuntimeSkipQuantifiers>False</CodeContractsRuntimeSkipQuantifiers>
<CodeContractsRunCodeAnalysis>False</CodeContractsRunCodeAnalysis>
<CodeContractsNonNullObligations>False</CodeContractsNonNullObligations>
<CodeContractsBoundsObligations>False</CodeContractsBoundsObligations>
<CodeContractsArithmeticObligations>False</CodeContractsArithmeticObligations>
<CodeContractsEnumObligations>False</CodeContractsEnumObligations>
<CodeContractsRedundantAssumptions>False</CodeContractsRedundantAssumptions>
<CodeContractsInferRequires>False</CodeContractsInferRequires>
<CodeContractsInferEnsures>False</CodeContractsInferEnsures>
<CodeContractsInferObjectInvariants>False</CodeContractsInferObjectInvariants>
<CodeContractsSuggestAssumptions>False</CodeContractsSuggestAssumptions>
<CodeContractsSuggestRequires>True</CodeContractsSuggestRequires>
<CodeContractsSuggestEnsures>False</CodeContractsSuggestEnsures>
<CodeContractsSuggestObjectInvariants>False</CodeContractsSuggestObjectInvariants>
<CodeContractsDisjunctiveRequires>False</CodeContractsDisjunctiveRequires>
<CodeContractsRunInBackground>True</CodeContractsRunInBackground>
<CodeContractsShowSquigglies>False</CodeContractsShowSquigglies>
<CodeContractsUseBaseLine>False</CodeContractsUseBaseLine>
<CodeContractsEmitXMLDocs>True</CodeContractsEmitXMLDocs>
<CodeContractsCacheAnalysisResults>True</CodeContractsCacheAnalysisResults>
<CodeContractsRuntimeCheckingLevel>Full</CodeContractsRuntimeCheckingLevel>
<CodeContractsReferenceAssembly>Build</CodeContractsReferenceAssembly>
<CodeContractsAnalysisWarningLevel>0</CodeContractsAnalysisWarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)' == 'Release' ">
<CodeContractsRuntimeCheckingLevel>ReleaseRequires</CodeContractsRuntimeCheckingLevel>
</PropertyGroup>
</Project>
If you have more than a few projects, I recommend putting these in a private nuget package and referencing that nuget package in each of your projects. The code contracts settings (from step 2) can go in your mycompany.codecontracts.props file, and the code contracts targets (from step 1) can go in your mycompany.codecontracts.targets file.
More info on packaging msbuild properties/targets in a nuget package here: https://learn.microsoft.com/en-us/nuget/create-packages/creating-a-package#including-msbuild-props-and-targets-in-a-package
I'm willing to provide an example on GitHub if there's sufficient interest.

I found the approaches suggested here were not straightforward, in particular that it would require the changes on each developer's machines and on the build server as well.
I decided to create my own very simplified version of Contract.Requires() that will need only global replace of the using declaration in caller classes.
using MYCommon.Diagnostics; //System.Diagnostics.Contracts;
When/if System.Diagnostics.Contracts will be available for VS 2017 and .NetStandard, it will be easy to revert to the proper version.
The actual class is:
/// <summary>
/// Contract.Requires(config != null); in VS 2017 not throw ArgumentNullException
/// The class is workaround for https://stackoverflow.com/questions/40767941/does-vs2017-work-with-codecontracts
/// </summary>
public class Contract
{
public static void Requires(bool condition, string message = null)
{
Requires<ArgumentNullException>(condition, message);
}
public static void Requires<TException>(bool condition, string message=null) where TException:Exception , new ()
{
if (!condition)
{
//https://stackoverflow.com/questions/41397/asking-a-generic-method-to-throw-specific-exception-type-on-fail/41450#41450
var e=default(TException);
try
{
message = message ?? "Unexpected Condition"; //TODO consider to pass condition as lambda expression
e = Activator.CreateInstance(typeof(TException), message) as TException;
}
catch (MissingMethodException ex)
{
e = new TException();
}
throw e;
}
}
}
The essential limitation is that typical usage Contract.Requires(param1!=null); doesn't allow me to throw the exception with the name of the parameter, and better usage is a bit longer:
Contract.Requires<ArgumentNullException>(param1!=null, "param1 is null");

Related

MSBuild Conditional PackageReference based on .Net TargetFramework

INTRODUCTION
I am building a class library which could be used by some legacy applications targetting .Net Framework 4.0 and new applications targetting .Net Framework 4.6.1
I am adding some database/Hibernate new code in the class library that requires .Net Framework 4.6.1. This new code is incompatible with .Net Framework 4.0 because the nuGet package FluentNHibernate 3.1.0 requires .Net Framework 4.6.1 and up. And legacy application does not require this functionnality.
WHAT I AM TRYING TO ACHIEVE
I am attempting to conditionnaly build the class library so one code base and the master git branch can be used to build a version compatible for either one or the other application.
So far, I have been able to:
Define a constant indicating the target framework (FWK40)
for use within .cs code to adjust code to target framework
Conditionally define the targetted framework (TargetFrameworkVersion)
Exclude files from build when not under the right TargetFrameworkVersion
Here is what the .CSPROJ looks so far (emphasis for the relevant adjustments):
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug.Net40|AnyCPU'">
<!-- Set target framework here -->
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
<DebugSymbols>true</DebugSymbols>
<OutputPath>bin\Debug.Net40\</OutputPath>
<!-- Define Build-time constant here -->
<DefineConstants Condition=" '$(TargetFrameworkVersion)' == 'v4.0'" >FWK40</DefineConstants>
</PropertyGroup>
<ItemGroup>
<-- Conditionally include .cs files here -->
<Compile Include="Database\GeneralSQL.cs" Condition="'$(TargetFrameworkVersion)' != 'v4.0'" />
<Compile Include="Database\NamingStrategy.cs" Condition="'$(TargetFrameworkVersion)' != 'v4.0'" />
<ItemGroup>
<ItemGroup>
<-- In THEORY conditionally include PackageReference here -->
<PackageReference Include="FluentNHibernate" Condition="'$(TargetFramework)' != 'net40'" >
<Version>3.1.0</Version>
</PackageReference>
</ItemGroup>
THE RESULT SO FAR
What is happenning, is I am getting a nuGet error saying:
NU1202: Package FluentNHibernate 3.1.0 is not compatible with net40 (.NETFramework,Version=v4.0). Package FluentNHibernate 3.1.0 supports:
Failed to restore C:\_projets\repos\TestSolution\TestLibrary\TestLibrary.csproj (in 19 ms).
NuGet package restore failed. Please see Error List window for detailed warnings and errors.
Not withstanding this error, the assemblies all are generated properly, the DLL Class Library itself, as well as an EXE Console application using that class library AND so far they run properly.
THE PROBLEM
I haven't been able to conditionnaly include nuGet a PackageReference.
AND The nuGet error still causes MSBuild.exe to fail, which prevents the CI/CD pipeline to work properly..
WHAT I HAVE TRIED
I have tried many many ways to get rid of nuget NU1202 error message.
#1 I have tried initially with other conditions based on $(TargetFrameworkVersion) which works througout the .csproj but to no avail.
#2 According to official documentation, nuGet ReferencePackage only supports conditions based on $(TargetFramework) adding-a-packagereference-condition as shown in the sample .csproj above. YET THIS STILL DOES NOT WORK.
I haven't been able to figure out so far what exactly the Property TargetFramework looks like. I ran MSBUILD.EXE in Verbosity level diagnostics, which dumps all the Properties, but TargetFramework wasn't listed (while others were)
I have tried to "reverse" the condition == 'net461' so that if the expected value is incorrect, it won't be included and the error would disappear => no effect, errors still there
#3 I have tried to define myself the TargetFramework property
<!-- Set target framework here -->
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
<TargetFramework>net40</TargetFramework>
The outcome would be much worse!
Visual Studio did not like it, the "Configuration Manager" broke down
it would not allow to set a specific Configuration for a project.
changing from Debug.Net40 to any other configuration (or loading the project) would show a nasty error message
Current solution contains incorrect configuration mappings. It may cause projects to not work properly
And the csproj was definitely not loaded properly either and project would be skip the build step.
WHERE I AM AT NOW
I am really stuck! Can't seem to find a way to make this work.
I would hate to have to have a branch master40 and a branch master just to handle this.
I would hate to have to have two csproj different files, unless I can somehow manage to share/include one into the other AND Visual Studio would not complain
The really really right thing would be to make the conditions on the ReferencePackage to actually work as intended.
What you want is multi-targeting.
The documentation you link seems to be only applicable for SDK-style projects.
AFAIK, multi-targeting is not available with the legacy-style project format.
I suggest migrating to the SDK-style project format.
A lot of things are much simpler there, not to mention better documented.
You can use a tool to do this, like hvanbakel/CsprojToVs2017 or dotnet/try-convert. Don't be fooled by its name and wrong usage of terminology.
(since this is also mixed up on SO all the time: yes, you can use the SDK-style format with .NET Framework TFMs; SDK-style has nothing to do with either TFM or Visual Studio version, but only with minimum required MSBuild version).
Once you have done that for your particular project, the documentation for multi-targeting applies and you can use Condition on $(TargetFramework) just like you have already done, in both your PackageReference and the Compile item group and pretty much anywhere you want.

Debugging .net core 3.1 library code published on github private nuget repository is broken?

In the last few days I've battled against an issue with debugging nuget packages that I still wasn't able to solve the way I want.
All this has been tested with visual studio 2022, updated to the latest version available.
We have a .NET 3.1 library published on github (private package).
We consume such library in many .NET 3.1 WebAPI backends that we develop.
We need to be able to debug such library.
GitHUB doesn't seem to support symbol servers at the moment, so I thought we had these 2 possibilities:
embed the pdb in the dll: this seemed the most straightforward solution and was the first I tried. By doing so on the core library, when we import that in a .NET webapi project and inspect the "modules" window, we can see that symbols for the dll have been loaded correctly; symbol file column reads: "OurLibrary.dll (embedded)"
include the pdb in the nupkg and then add a piece of code (found here https://github.com/dotnet/sdk/issues/1458#issuecomment-420456386) in the .csproj of consuming .NET webapi project that ensures that the dll pdb, contained in the nuget package, is copied to the bin folder. Also in this case, inspecting the modules window, it looks that the symbols have been loaded from metadata (which I guess is the pdb file itself).
STILL, in both cases, if the project is running, when I try to set a breakpoint in the Startup.cs file of the consuming WebAPI project, and step into an IServiceCollection extension method, which is defined in the library, I'm able to do so, but many symbols used in that file (referring to PUBLIC types defined in the library, or from the framework itself) are white, and I can't explore them by doing "go to definintion".
Instead, if I try to peek at the source code of the extension method mentioned before, when the project is not running, I'm able to peek at code by doing "go to definition" without issues. So, I set a breakpoint..
Then, when I launch the project:
you can see that it's a different "SessionFactory" file, and all the symbols have become white. If I try to go back to the original file (with all the types correctly resolved by intellisense), and set a breakpoint inside it, visual studio automatically switches to the other file (with "broken" intellisense) and sets the breakpoint there, which is very frustrating..
At the moment the only solution that really behaves the way I want requires me to remove the library nuget package from the project and reference the library as an "Existing project" inside the solution. By doing so everything works perfectly (of course, now library source code is part of the project) but of course seems wrong / time consuming / error prone.
Somebody is able to shed some light on what is going on? Thanks
EDIT: FURTHER DETAILS FOR USER #Transformer
I tried your suggestion to include the supplied code in .csproj of both the library and the consuming application:
By doing so in the library .csproj, it contains these settings related to PDB generation, in a property group:
<EmbedAllSources>true</EmbedAllSources>
<DebugSymbols>true</DebugSymbols>
<DebugType>portable</DebugType>
<AllowedReferenceRelatedFileExtensions>.pdb</AllowedReferenceRelatedFileExtensions>
<GeneratePackageOnBuild>True</GeneratePackageOnBuild>
It also includes this, outside of the property group:
<Target Name="AddReferenceRelatedPathsToCopyLocal" AfterTargets="ResolveAssemblyReferences">
<ItemGroup>
<ReferenceCopyLocalPaths Include="#(_ReferenceRelatedPaths)" />
</ItemGroup>
</Target>
Unfortunately, by doing so, the pdb doesn't seem to be included in the nupkg. Instead, if I add the following (a setting I've already found in the past):
<AllowedOutputExtensionsInPackageBuildOutputFolder>$(AllowedOutputExtensionsInPackageBuildOutputFolder);.pdb</AllowedOutputExtensionsInPackageBuildOutputFolder>
then the pdb is included in nupkg, but still, I experience the same debugging problem in the consuming library, even if I add the code you supplied to the consuming library as well...any other idea?
Thanks a lot for your kind help
The issue is probably because the nuget packages are built with Release configuration which optimizes out the symbols. One way you can debug the package itself is if you open the project (from which you deploy the nuget), build it with Debug configuration, then copy the dll and pdb file into the bin\Debug\ folder of your consumer app. Then start the consumer app with no debugger attached, after it starts, you can attach your nuget project to that process, and your nuget code breakpoints will be hit.
Hello, from what I can see - that's because the embedded files are not copied to local, please try this in your cs.proj file and paste your comments
<PropertyGroup>
<AllowedReferenceRelatedFileExtensions>.pdb</AllowedReferenceRelatedFileExtensions>
</PropertyGroup>
<Target Name="AddReferenceRelatedPathsToCopyLocal" AfterTargets="ResolveAssemblyReferences">
<ItemGroup>
<ReferenceCopyLocalPaths Include="#(_ReferenceRelatedPaths)" />
</ItemGroup>
</Target>
Question from Carlo Arnaboldi : Where does this go?
Update: These are settings that go into the .proj file.
You you to do this in your nuget pacakge && your consuming project to see the pdb for symbol debugging
Also delete you old pdbs - exist visual studio/code and then delete the bin and obj folders

.NET Analyzer: Package Version vs Assembly Version

As you can see in the following picture when you create a project of type Analyzer with Code Fix (.NET Standard) using VS 2017, in the properties tab of the project there is package version, assembly version and assembly file version.
Are those 3 versions related together or not? Also, as I make changes in the project how am I supposed to change the versions number? For instance, if I fix a bug, if I add a new rule, etc.
Are those 3 versions related together or not? Also, as I make changes in the project how am I supposed to change the versions number? For instance, if I fix a bug, if I add a new rule, etc.
Before answering this question, we need to know some info about the AssemblyVersionand AssemblyFileVersion.
Assembly Version: This is the version that .Net looks at during run-time for loading packages and finding types.
Assembly File Version: This defines the version reported by the OS to other applications like Windows Explorer.
You can see the Rémy van Duijkeren`s answer for some more details.
However, NuGet doesn’t use either of these. It uses a third versioning attribute: AssemblyInformationalVersion - the Product version of the assembly.
It uses this attribute because nothing else seems to care about it. The informational version isn’t used by the OS or by .Net, which means it’s available for NuGet to claim. But this versioning attribute was removed in the AssemblyInfo.cs file, because they don’t apply to semantic versioning.
When you are in the project of type Analyzer with Code Fix (.NET Standard) using VS 2017, those attributes settings has moved into the .csproj file. By default they don't show up but you can discover them from Visual Studio 2017 in the project properties Package tab:
Once saved those values can be found in MyProject.csproj:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net461</TargetFramework>
<Version>1.2.3.4</Version>
<Authors>Author 1</Authors>
<Company>Company XYZ</Company>
<Product>Product 2</Product>
<PackageId>MyApp</PackageId>
<AssemblyVersion>2.0.0.0</AssemblyVersion>
<FileVersion>3.0.0.0</FileVersion>
<NeutralLanguage>en</NeutralLanguage>
<Description>Description here</Description>
<Copyright>Copyright</Copyright>
<PackageLicenseUrl>License URL</PackageLicenseUrl>
<PackageProjectUrl>Project URL</PackageProjectUrl>
<PackageIconUrl>Icon URL</PackageIconUrl>
<RepositoryUrl>Repo URL</RepositoryUrl>
<RepositoryType>Repo type</RepositoryType>
<PackageTags>Tags</PackageTags>
<PackageReleaseNotes>Release</PackageReleaseNotes>
</PropertyGroup>
In the file explorer properties information tab, Version is shown as "Product version", which is used by NuGet. Just like the versioning attribute: AssemblyInformationalVersion.
So, if you fix a bug or add a new rule, you can change the package version for shipping new package.
major is incremented for a breaking change, minor for a change that
is backwards compatible and patch for bug fixes.
As to whether it needs to be modified the versions number for Assembly Versions, you can refer to this document for some more details.
Hope this helps.

Postsharp not building in custom configuration via MSBuild

I'm running MSBuild via command line on a customer configuration (like Debug, Release that you see in Visual Studio, except I'm using my own one).
MSBuild build.msbuild /p:Configuration=Dev ...blah
C:\myproject\packages\PostSharp.4.3.9-alpha\tools\PostSharp.targets(422,5):
error MSB4036: The "GenerateBindingRedirects" task was not found.
Check the following: 1.) The name of the task in the project file is
the same as the name o f the task class. 2.) The task class is
"public" and implements the Microsoft.Build.Framework.ITask interface.
3.) The task is correctly declared with in the project file, or in the *.tasks files located in the
"C:\windows\Microsoft.NET\Frame work64\v4.0.30319" directory. [path to
my proj file]
This normally works fine, but when I have postsharp it's throwing an error as you can see above. When I replace Dev in the /p:Configuration with Debug or Release they're working fine.
I checked the .csproj and nothing special is being added by Release that's not in my Dev configuration.
What should I do to fix this? I tried copying the contents of the postsharp package directory into the bin\Dev folder but it's still not able to find the tasks.
I ran into this error in my .NET 4.0 project upgrading PostSharp from 2.1.6 to 6.0.27, launching the Release build with a script suddenly MSBuild (version 4.7.3056) stopped to work.
The problem is due to the task GenerateBindingRedirects declared inside PostSharp.targets (in package directory) which hasn't a corresponding <UsingTask TaskName="Microsoft.Build.Tasks.GenerateBindingRedirects" inside the .csproj.
Apparently the fastest way to "solve" is to add <PostSharpDisableDefaultBindingRedirects>True</PostSharpDisableDefaultBindingRedirects> inside the PostSharp.Custom.targets, as suggested here http://doc.postsharp.net/assembly-binding-resolution. But depending on the project it could be dangerous.
It didn't work for me because the .NET framework of my project is too old, but in theory a solution could be to add the package to the project and declaring the UsingTask element inside the .csproj:
Install-Package Microsoft.Build.Tasks.Core -Version 15.1.0
<UsingTask TaskName="Microsoft.Build.Tasks.GenerateBindingRedirects" AssemblyName="Microsoft.Build.Tasks.Core, Version=15.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" Condition="'$(MSBuildAssemblyVersion)' != ''" />
Other workarounds are the removal of element GenerateBindingRedirects declared inside PostSharp.targets (adding this file to the git tracked files), or to add an override of that element in the .csproj files of the projects where there is the problem (something like this):
<Target Name="PostSharpGenerateBindingRedirects" DependsOnTargets="ResolveAssemblyReferences" Inputs="$(MSBuildAllProjects);#(AppConfigFile);$(ResolveAssemblyReferencesStateFile);$(IntermediateOutputPath)" Outputs="$(_DefaultPostSharpHostConfigurationFile)" />
We just ran into the same situation. Upgrading from PostSharp 2 to 6.0.33.
Our Jenkins build failed with this same error when building the Release configuration.
#Mauro Picotti suggestions were helpful, however installing the Microsoft.Build.Tasks.Core package didn't work for us either because it requires .NET 4.5+, and we target .NET 4.0.
And the other suggestions simply disable the binding redirects which is dangerous as Mauro says. That could lead to very difficult to diagnose compilation errors down the track.
What ultimately ended up working for us was telling Jenkins to use a new version of MS Build. Instead of MS Build 4.0, we call the MS Build from VS 2013 or VS 2017 and it appears to have the GenerateBindingRedirects task available and builds fine.

MSBuild .NET project that will output existing assembly as it's result

I need to create csproj file that will be usable as project reference in VS2013 and will output prebuilt binary as it's "Build" result.
We use referenced projects for build, however company policy doesn't allow access to some of that projects for everyone. As a result projects need to be updated manually to make them build. This is really a major inconvenience when switching branches and when making edits to project files, so I want to create dummy project that will be bound to pre-built binaries as their "output" and will be placed instead of real projects.
EDIT: Moving that assembly to Nuget package is not an option for now since Nuget has some issues with dev flow (when you need to debug/test/develop package). I saw some VS extension that implements switching between Nuget package and local project which might solve this issue, but I'm not sure if it will be accepted and want to explore other options.
To be clear - the thing I want to avoid is editing project in any way, so that project can be built cleanly after pulling it from Git, and I don't have to clean it every time before commit.
I haven't properly tested it, but the solution seems really simple (if I understand the question properly).
Just add this to the existing .csproj, overriding the Build target to just give the path to the pre-built assembly.
<Target
Name="Build"
Returns="$(TargetPath)" />
This assumes the TargetPath property already defined, and it should automatically be if you're modifying the original .csproj. Otherwise just define it yourself in a <PropertyGroup> before the Build task.
Note that having TargetPath defined is important for the ProjectReferences in your own project to resolve.
How about having those restricted (binary only) projects reside in an internal Nuget package feed, so that Nuget can install the packages as needed, on build?

Categories