dotnet, aspnet, build, autofac comments edit

We recently released Autofac 4.0.0-beta8-157 to NuGet to coincide with the DNX beta 8 release. As part of that update, we re-added the classic PCL target .NETPortable,Version=v4.5,Profile=Profile259 (which is portable-net45+dnxcore50+win+wpa81+wp80+MonoAndroid10+Xamarin.iOS10+MonoTouch10) because older VS versions and some project types were having trouble finding a compatible version of Autofac 4.0.0 - they didn’t rectify the dotnet target framework as a match.

If you’re not up on the dotnet target framework moniker, Oren Novotny has some great articles that help a lot:

I’m now working on a beta 8 compatible version of Autofac.Configuration. For beta 7 we’d targeted dnx451, dotnet, and net45. I figured we could just update to start using Autofac 4.0.0-beta8-157, rebuild, and call it good.

Instead, I started getting a lot of build errors when targeting the dotnet framework moniker.

Building Autofac.Configuration for .NETPlatform,Version=v5.0
  Using Project dependency Autofac.Configuration 4.0.0-beta8-1
    Source: E:\dev\opensource\Autofac\Autofac.Configuration\src\Autofac.Configuration\project.json

  Using Package dependency Autofac 4.0.0-beta8-157
    Source: C:\Users\tillig\.dnx\packages\Autofac\4.0.0-beta8-157
    File: lib\dotnet\Autofac.dll

  Using Package dependency Microsoft.Framework.Configuration 1.0.0-beta8
    Source: C:\Users\tillig\.dnx\packages\Microsoft.Framework.Configuration\1.0.0-beta8
    File: lib\dotnet\Microsoft.Framework.Configuration.dll

  Using Package dependency Microsoft.Framework.Configuration.Abstractions 1.0.0-beta8
    Source: C:\Users\tillig\.dnx\packages\Microsoft.Framework.Configuration.Abstractions\1.0.0-beta8
    File: lib\dotnet\Microsoft.Framework.Configuration.Abstractions.dll

  Using Package dependency System.Collections 4.0.11-beta-23409
    Source: C:\Users\tillig\.dnx\packages\System.Collections\4.0.11-beta-23409
    File: ref\dotnet\System.Collections.dll

  (...and some more package dependencies that got resolved, then...)

  Unable to resolve dependency fx/System.Collections

  Unable to resolve dependency fx/System.ComponentModel

  Unable to resolve dependency fx/System.Core

  (...and a lot more fx/* items unresolvable.)

This was, at best, confusing. I mean, in the same target framework, I see these two things together:

  Using Package dependency System.Collections 4.0.11-beta-23409
    Source: C:\Users\tillig\.dnx\packages\System.Collections\4.0.11-beta-23409
    File: ref\dotnet\System.Collections.dll

  Unable to resolve dependency fx/System.Collections

So it found System.Collections, but it didn’t find System.Collections. Whaaaaaaa?!

After a lot of searching (with little success) I found David Fowler’s indispensible article on troubleshooting dependency issues in ASP.NET 5. This led me to the dnu list --details command, where I saw this:

[Target framework .NETPlatform,Version=v5.0 (dotnet)]

Framework references:
  fx/System.Collections  - Unresolved
    by Package: Autofac 4.0.0-beta8-157

  fx/System.ComponentModel  - Unresolved
    by Package: Autofac 4.0.0-beta8-157

  (...and a bunch more of these...)


Package references:
* Autofac 4.0.0-beta8-157
    by Project: Autofac.Configuration 4.0.0-beta8-1

* Microsoft.Framework.Configuration 1.0.0-beta8
    by Project: Autofac.Configuration 4.0.0-beta8-1

  Microsoft.Framework.Configuration.Abstractions 1.0.0-beta8
    by Package: Microsoft.Framework.Configuration 1.0.0-beta8

  System.Collections 4.0.11-beta-23409
    by Package: Autofac 4.0.0-beta8-157...
    by Project: Autofac.Configuration 4.0.0-beta8-1

  (...and so on.)

Hold up - Autofac 4.0.0-beta8-157 needs both the framework assembly and the dependency package for System.Collections?

Looking in the generated .nuspec file for the updated core Autofac, I see:

<?xml version="1.0"?>
<package xmlns="http://schemas.microsoft.com/packaging/2012/06/nuspec.xsd">
  <metadata>
    <!-- ... -->
    <dependencies>
      <group targetFramework="DNX4.5.1" />
      <group targetFramework=".NETPlatform5.0">
        <dependency id="System.Collections" version="4.0.11-beta-23409" />
        <dependency id="System.Collections.Concurrent" version="4.0.11-beta-23409" />
        <!-- ... -->
      </group>
      <group targetFramework=".NETFramework4.5" />
      <group targetFramework=".NETCore4.5" />
      <group targetFramework=".NETPortable4.5-Profile259" />
    </dependencies>
    <frameworkAssemblies>
      <!-- ... -->
      <frameworkAssembly assemblyName="System.Collections" targetFramework=".NETPortable4.5-Profile259" />
      <frameworkAssembly assemblyName="System.ComponentModel" targetFramework=".NETPortable4.5-Profile259" />
      <frameworkAssembly assemblyName="System.Core" targetFramework=".NETPortable4.5-Profile259" />
      <frameworkAssembly assemblyName="System.Diagnostics.Contracts" targetFramework=".NETPortable4.5-Profile259" />
      <frameworkAssembly assemblyName="System.Diagnostics.Debug" targetFramework=".NETPortable4.5-Profile259" />
      <frameworkAssembly assemblyName="System.Diagnostics.Tools" targetFramework=".NETPortable4.5-Profile259" />
      <!-- ... -->
    </frameworkAssemblies>
  </metadata>
</package>

The list of failed fx/* dependencies is exactly the same as the list of frameworkAssembly references that target .NETPortable4.5-Profile259 in the .nuspec.

By removing the dotnet target framework moniker from Autofac.Configuration and compiling for specific targets, everything resolves correctly.

What I originally thought was that dotnet indicated, basically, “I support what my dependencies support,” which I took to mean, “we’ll figure out the lowest common denominator of all the dependencies and that’s the set of stuff this supports.”

What dotnet appears to actually mean is, “I support the superset of everything my dependencies support.”

The reason I take that away is that the Microsoft.Framework.Configuration 1.0.0-beta8 package targets net45, dnx451, dnxcore, and dotnet - but it doesn’t specifically support .NETPortable,Version=v4.5,Profile=Profile259. I figured Autofac.Configuration, targeting dotnet, would rectify to support the common frameworks that both core Autofac and Microsft.Framework.Configuration support… which would mean none of the <frameworkAssembly /> references targeting .NETPortable4.5-Profile259 would need to be resolved to build Autofac.Configuration.

Since they do, apparently, need to be resolved, I have to believe dotnet implies superset rather than subset.

This appears to mostly just be a gotcha if you have a dependency that targets one of the older PCL framework profiles. If everything down the stack just targets dotnet it seems to magically work.

If you’d like to try this and see it in action, check out the Autofac.Configuration repo at 14c10b5bf6 and run the build.ps1 build script.

autofac, dotnet comments edit

As part of DNX RC1, the Microsoft.Framework.* packages are getting renamed to Microsoft.Extensions.*.

The Autofac.Framework.DependencyInjection package was named to follow along with the pattern established by those libraries: Microsoft.Framework.DependencyInjection -> Autofac.Framework.DependencyInjection.

With the RC1 rename of the Microsoft packages, we’ll be updating the name of the Autofac package to maintain consistency: Autofac.Extensions.DependencyInjection. This will happen for Autofac as part of beta 8.

We’ll be doing the rename as part of the beta 8 drop since beta 8 appears to have been pushed out by a week and we’d like to get a jump on things. For beta 8 we’ll still refer to the old Microsoft dependency names to maintain compatibility but you’ll have a new Autofac dependency. Then when RC1 hits, you won’t have to change the Autofac dependency because it’ll already be in line.

You can track the rename on Autofac issue #685.

powershell, vs, dotnet comments edit

I love PowerShell, but I do a lot with the Visual Studio developer prompt and that’s still good old cmd.

Luckily, you can make your PowerShell prompt also a Visual Studio prompt.

First, go get the PowerShell Community Extensions. If you’re a PowerShell user you should probably have these already. You can either get them from the CodePlex site directly or install via Chocolatey.

Now, in your PowerShell profile (stored at %UserProfile%\Documents\WindowsPowerShell\Microsoft.PowerShell_profile.ps1) add the following:

Import-Module Pscx

# Add Visual Studio 2015 settings to PowerShell
Import-VisualStudioVars 140 x86

# If you'd rather use VS 2013, comment out the
# above line and use this one instead:
# Import-VisualStudioVars 2013 x86

Next time you open a PowerShell prompt, it’ll automatically load up the Visual Studio variables to also make it a Visual Studio prompt.

Take this to the next level by getting a “PowerShell Prompt Here” context menu extension and you’re set!

dotnet, build, tfs comments edit

I’m working with some builds in Visual Studio Online which, right now, is basically Team Foundation Server 2015. As part of that, I wanted to do some custom work in my build script but only if the build was running in TFS.

The build runs using the Visual Studio Build build step. I couldn’t find any documentation for what additional / special environment variables where available, so I ran a small build script like this…

<Exec Command="set" />

…and got the environment variables. For reference, here’s what you get when you run the Visual Studio Build task on an agent with Visual Studio 2015:

agent.jobstatus=Succeeded
AGENT_BUILDDIRECTORY=C:\a\ba99c3da
AGENT_HOMEDIRECTORY=C:\LR\MMS\Services\Mms\TaskAgentProvisioner\Tools
AGENT_ID=1
AGENT_JOBNAME=Build
AGENT_MACHINENAME=TASKAGENT-0001
AGENT_NAME=Hosted Agent
AGENT_ROOTDIRECTORY=C:\a
AGENT_WORKFOLDER=C:\a
AGENT_WORKINGDIRECTORY=C:\a\SourceRootMapping\2808d0ee-383a-4503-86cd-e9c64da409e3\Job-070e8691-db73-41a3-88e3-97deaf4dd9a1
ALLUSERSPROFILE=C:\ProgramData
ANDROID_HOME=C:\java\androidsdk\android-sdk
ANDROID_NDK_HOME=C:\java\androidsdk\android-ndk-r10d
ANT_HOME=C:\java\ant\apache-ant-1.9.4
APPDATA=C:\Users\buildguest\AppData\Roaming
build.fetchtags=false
BUILDCONFIGURATION=release
BUILDPLATFORM=any cpu
BUILD_ARTIFACTSTAGINGDIRECTORY=C:\a\ba99c3da\artifacts
BUILD_BUILDID=15
BUILD_BUILDNUMBER=2015.09.17.3
BUILD_BUILDURI=vstfs:///Build/Build/15
BUILD_CONTAINERID=85945
BUILD_DEFINITIONNAME=Continuous Integration
BUILD_DEFINITIONVERSION=8
BUILD_QUEUEDBY=[DefaultCollection]\Project Collection Service Accounts
BUILD_QUEUEDBYID=a75bc823-f51a-48bc-8ec8-4d7dacaf7dc9
BUILD_REPOSITORY_CLEAN=True
BUILD_REPOSITORY_GIT_SUBMODULECHECKOUT=False
BUILD_REPOSITORY_LOCALPATH=C:\a\ba99c3da\MyProject
BUILD_REPOSITORY_NAME=MyProject
BUILD_REPOSITORY_PROVIDER=TfsGit
BUILD_REPOSITORY_URI=https://myvsoproject.visualstudio.com/DefaultCollection/_git/MyProject
BUILD_REQUESTEDFOR=Your Name Here
BUILD_REQUESTEDFORID=8c477f14-acc1-4765-b1a0-ec6cfb88740d
BUILD_SOURCEBRANCH=refs/heads/master
BUILD_SOURCEBRANCHNAME=master
BUILD_SOURCESDIRECTORY=C:\a\ba99c3da\MyProject
BUILD_SOURCESDIRECTORYHASH=ba99c3da
BUILD_SOURCEVERSION=91c1ef45e3fcc91873cd599d4a7e2e1adf15d9a5
BUILD_STAGINGDIRECTORY=C:\a\ba99c3da\staging
CommonProgramFiles=C:\Program Files (x86)\Common Files
CommonProgramFiles(x86)=C:\Program Files (x86)\Common Files
CommonProgramW6432=C:\Program Files\Common Files
COMPUTERNAME=TASKAGENT-0001
ComSpec=C:\Windows\system32\cmd.exe
CORDOVA_CACHE=C:\cordova\cli
CORDOVA_DEFAULT_VERSION=5.1.1
CORDOVA_HOME=C:\cordova\cli\_cordova
EnableNuGetPackageRestore=True
FP_NO_HOST_CHECK=NO
GRADLE_USER_HOME=C:\java\gradle\user
GTK_BASEPATH=C:\Program Files (x86)\GtkSharp\2.12\
JAVA_HOME=C:\java\jdk\jdk1.8.0_25
LOCALAPPDATA=C:\Users\buildguest\AppData\Local
M2_HOME=C:\java\maven\apache-maven-3.2.2
MSBuildLoadMicrosoftTargetsReadOnly=true
NPM_CONFIG_CACHE=C:\NPM\Cache
NPM_CONFIG_PREFIX=C:\NPM\Modules
NUMBER_OF_PROCESSORS=2
OS=Windows_NT
Path=C:\LR\MMS\Services\Mms\TaskAgentProvisioner\Tools\agent\worker\Modules\Microsoft.TeamFoundation.DistributedTask.Task.Internal\NativeBinaries\amd64;C:\ProgramData\Oracle\Java\javapath;C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0\;C:\Program Files (x86)\Microsoft SQL Server\100\Tools\Binn\;C:\Program Files\Microsoft SQL Server\100\Tools\Binn\;C:\Program Files\Microsoft SQL Server\100\DTS\Binn\;C:\Program Files (x86)\Microsoft ASP.NET\ASP.NET Web Pages\v1.0\;C:\Program Files\Microsoft SQL Server\110\Tools\Binn\;C:\Program Files (x86)\Microsoft SDKs\TypeScript\1.0\;C:\Program Files\Microsoft SQL Server\120\Tools\Binn\;C:\Users\VssAdministrator\.dnx\bin;C:\Program Files\Microsoft DNX\Dnvm\;C:\Program Files (x86)\Windows Kits\10\Windows Performance Toolkit\;C:\Program Files (x86)\Microsoft Emulator Manager\1.0\;C:\Program Files (x86)\GtkSharp\2.12\bin;C:\Program Files (x86)\Microsoft SDKs\TypeScript\1.4\;C:\Program Files (x86)\Git\bin;C:\Program Files (x86)\Microsoft SQL Server\110\Tools\Binn\ManagementStudio\;C:\Program Files (x86)\Microsoft SQL Server\110\Tools\Binn\;C:\Program Files (x86)\Microsoft Visual Studio 11.0\Common7\IDE\PrivateAssemblies\;C:\Program Files (x86)\Microsoft SQL Server\110\DTS\Binn\;C:\Program Files (x86)\Microsoft SQL Server\120\Tools\Binn\ManagementStudio\;C:\Program Files (x86)\Microsoft SQL Server\120\Tools\Binn\;C:\Program Files (x86)\Microsoft Visual Studio 12.0\Common7\IDE\PrivateAssemblies\;C:\Program Files (x86)\Microsoft SQL Server\120\DTS\Binn\;C:\Program Files\Microsoft\Web Platform Installer\;C:\NPM\Modules;C:\Program Files\nodejs\;C:\NPM\Modules;C:\cordova;C:\java\ant\apache-ant-1.9.4\bin;
PATHEXT=.COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH;.MSC;.CPL
PLUGMAN_HOME=C:\cordova\cli\_plugman
PROCESSOR_ARCHITECTURE=x86
PROCESSOR_ARCHITEW6432=AMD64
PROCESSOR_IDENTIFIER=Intel64 Family 6 Model 45 Stepping 7, GenuineIntel
PROCESSOR_LEVEL=6
PROCESSOR_REVISION=2d07
ProgramData=C:\ProgramData
ProgramFiles=C:\Program Files (x86)
ProgramFiles(x86)=C:\Program Files (x86)
ProgramW6432=C:\Program Files
PROMPT=$P$G
PSModulePath=C:\Users\buildguest\Documents\WindowsPowerShell\Modules;C:\Program Files\WindowsPowerShell\Modules;C:\Windows\system32\WindowsPowerShell\v1.0\Modules\;C:\Program Files\SharePoint Online Management Shell\;C:\Program Files (x86)\Microsoft SQL Server\110\Tools\PowerShell\Modules\;C:\Program Files (x86)\Microsoft SQL Server\120\Tools\PowerShell\Modules\;C:\Program Files (x86)\Microsoft SDKs\Azure\PowerShell\ServiceManagement;C:\LR\MMS\Services\Mms\TaskAgentProvisioner\Tools\agent\worker\Modules
PUBLIC=C:\Users\Public
SYSTEM=mstf
SystemDrive=C:
SystemRoot=C:\Windows
SYSTEM_ARTIFACTSDIRECTORY=C:\a\ba99c3da
SYSTEM_COLLECTIONID=2808d0ee-383a-4503-86cd-e9c64da409e3
SYSTEM_DEFAULTWORKINGDIRECTORY=C:\a\ba99c3da\MyProject
SYSTEM_DEFINITIONID=1
SYSTEM_HOSTTYPE=build
SYSTEM_TEAMFOUNDATIONCOLLECTIONURI=https://myvsoproject.visualstudio.com/DefaultCollection/
SYSTEM_TEAMFOUNDATIONSERVERURI=https://myvsoproject.visualstudio.com/DefaultCollection/
SYSTEM_TEAMPROJECT=MyProject
SYSTEM_TEAMPROJECTID=a9f2e0a9-752d-4529-a657-35a421584815
SYSTEM_WORKFOLDER=C:\LR\MMS\Services\Mms\TaskAgentProvisioner\Tools\_work
TEMP=C:\Users\BUILDG~1\AppData\Local\Temp
TF_BUILD=True
TMP=C:\Users\BUILDG~1\AppData\Local\Temp
USERDOMAIN=TASKAGENT-0001
USERNAME=buildguest
USERPROFILE=C:\Users\buildguest
VS100COMNTOOLS=C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\Tools\
VS110COMNTOOLS=C:\Program Files (x86)\Microsoft Visual Studio 11.0\Common7\Tools\
VS120COMNTOOLS=C:\Program Files (x86)\Microsoft Visual Studio 12.0\Common7\Tools\
VS140COMNTOOLS=C:\Program Files (x86)\Microsoft Visual Studio 14.0\Common7\Tools\
VSSDK110Install=C:\Program Files (x86)\Microsoft Visual Studio 11.0\VSSDK\
VSSDK120Install=C:\Program Files (x86)\Microsoft Visual Studio 12.0\VSSDK\
VSSDK140Install=C:\Program Files (x86)\Microsoft Visual Studio 14.0\VSSDK\
windir=C:\Windows
WIX=C:\Program Files (x86)\WiX Toolset v3.7\
XNAGSShared=C:\Program Files (x86)\Common Files\Microsoft Shared\XNA\

Note that BUILDCONFIGURATION and BUILDPLATFORM are parameters to the Visual Studio Build task. You’ll see that text right in the TFS build system dashboard.

The BUILD_BUILDNUMBER value is the one I’m the most interested in - that’s what I can key off to set the assembly version. TF_BUILD seems to be what you use to determin if the build is running in TFS.

autofac, dotnet comments edit

In the continuing journey toward the Autofac 4.0.0 release, some integration/extras packages have been released:

  • Autofac.Wcf 4.0.0: Doesn’t require Autofac 4.0 but is tested to be compatible with it. .NET 4.0 framework support is removed; minimum is now .NET 4.5. No interface changes were made - the major semver increment is for the .NET compatibility break. AllowPartiallyTrustedCallers and other pre-4.5 security markings are also removed.
  • Autofac.Mef 4.0.0: Doesn’t require Autofac 4.0 but is tested to be compatible with it. .NET 4.0 framework support is removed; minimum is now .NET 4.5. No interface changes were made - the major semver increment is for the .NET compatibility break. AllowPartiallyTrustedCallers and other pre-4.5 security markings are also removed.
  • Autofac.Extras.AttributeMetadata 4.0.0: This is a rename from Autofac.Extras.Attributed to Autofac.Extras.AttributeMetadata to express what it actually attributes. Doesn’t require Autofac 4.0 but is tested to be compatible with it. Requires Autofac.Mef 4.0 due to the security attribute changes and minimum .NET 4.5 requirement.
  • Autofac.Multitenant.Wcf 4.0.0-beta7-223: The WCF component compatible with Autofac.Multitenant 4.0 beta. This will stay in beta until Autofac.Multitenant can also be fully released. This is a rename from Autofac.Extras.Multitenant.Wcf to match the rename of Autofac.Extras.Multitenant to Autofac.Multitenant. Requires Autofac.Wcf 4.0 due to the security attribute changes and minimum .NET 4.5 requirement.

There’s a lot going on to try and keep up with DNX compatibility (where possible) and checking/testing existing integration packages to ensure they still work with Autofac 4. For the most part, it seems just updating things to use .NET 4.5 instead of .NET 4.0 allows us to retain forward-compatibility, though in some cases the code access security changes require changes.

We’re working hard on it. Watch our Twitter feed for announcements!