Friday, June 24, 2011

Database Unit Tests - Config Transforms

I wanted to have a configuration for the other environments to run the same tests.


  1. started out adding the sit configuration to the solution and the test project.
  2. I added the following to my Db.Tests.csproj:
    1. top property group under projectguid:
      1. <ProjectConfigFileName>App.Config</ProjectConfigFileName>
    2. and just below outputType:
      1. <OutputExtension Condition="'$(OutputExtension)' == '' ">dll</OutputExtension>
    3. then in the item group with app.config:
      1. <Content Include="App.Sit.config">      <DependentUpon>app.Config</DependentUpon>    </Content>
    4. finally just before /Project tag:



<Import Condition="'$(Configuration)' == 'Sit'" Project="$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v10.0\WebApplications\Microsoft.WebApplication.targets" />
  <Target Condition="'$(Configuration)' == 'Sit'" Name="PostTransformAppConfig" AfterTargets="TransformWebConfig">
    <Copy Condition="Exists('$(TransformWebConfigIntermediateLocation)\transformed\App.config')" SourceFiles="$(TransformWebConfigIntermediateLocation)\transformed\App.config" DestinationFiles="$(OutputPath)\$(AssemblyName).$(OutputExtension).config" />
    <Copy Condition="Exists('$(TransformWebConfigIntermediateLocation)\transformed\App.config')" SourceFiles="$(TransformWebConfigIntermediateLocation)\transformed\App.config" DestinationFiles="$(OutputPath)\$(AssemblyName).vshost.$(OutputExtension).config" />
  </Target>
  <Target Condition="'$(Configuration)' == 'Sit'" Name="PostTransformAppConfig" AfterTargets="Build">
    <CallTarget Targets="TransformWebConfig" />
    <Copy Condition="Exists('$(TransformWebConfigIntermediateLocation)\transformed\App.config')" SourceFiles="$(TransformWebConfigIntermediateLocation)\transformed\App.config" DestinationFiles="$(OutputPath)\$(AssemblyName).$(OutputExtension).config" />
    <Copy Condition="Exists('$(TransformWebConfigIntermediateLocation)\transformed\App.config')" SourceFiles="$(TransformWebConfigIntermediateLocation)\transformed\App.config" DestinationFiles="$(OutputPath)\$(AssemblyName).vshost.$(OutputExtension).config" />
  </Target>



Here's my app.sit.config transform file:

<ExecutionContext xdt:Transform="Replace" Provider="System.Data.SqlClient" ConnectionString="Data Source=SitServer;Initial Catalog=Init1_SIT;Integrated Security=True;Pooling=False"
        CommandTimeout="30" />
    <PrivilegedContext xdt:Transform="Replace" Provider="System.Data.SqlClient" ConnectionString="Data Source=SitServer;Initial Catalog=Init1_SIT;Integrated Security=True;Pooling=False"
          CommandTimeout="30" />



Based on

Wednesday, June 1, 2011

Workflow quirk: cannot access this inline location reference

Activity '{0}' cannot access this inline location reference because it is only valid for activity '{1}'. Only the activity which obtained the inline location reference is allowed to use it.

Inside my assign activity:
' foundfiles is IEnumerable(of String)
foundFiles.Where(Function(file As String) FileNameBlacklist.Any(Function(blacklistItem) System.IO.Path.GetFileName(file).StartsWith(blacklistItem)) = False)

Not sure if this or the subsequent access was failing, however changing it to this fixed it:

foundFiles.Where(Function(file As String) FileNameBlacklist.Any(Function(blacklistItem) System.IO.Path.GetFileName(file).StartsWith(blacklistItem)) = False).ToList().AsEnumerable

Tuesday, May 31, 2011

Mashup: Team Foundation Server's API and Microsoft Active Directory

I wanted to know the userID and name of anyone that checked out a file in the last 2 months for edit on a specific path inside Tfs. Some of this code was tested to work fine on Tfs2010, but no guarantees.

So it's a nice little bit of code to connect to tfs, get the changes and then pull the names in from active directory with a max of 1 attempt per distinct userID.


Tuesday, May 24, 2011

.wdproj fails to copy down .refresh binaries

So I have recently been put on a team that utilizes web site projects and hooking up build automation.

Apparently the default target for copying down .dll.refresh files does in
C:\Program Files\MSBuild\Microsoft\WebDeployment\v10.0
this for its copy inside the _ResolveReferences target:

 <Copy 
      SourceFiles="@(References->'%(FullPath)')" 
      DestinationFolder="$(_FullSourceWebDir)\Bin\" 
      Condition="!Exists('%(References.Identity)')" 
      ContinueOnError="true"
      SkipUnchangedFiles="true"
      Retries="$(CopyRetryCount)"
      RetryDelayMilliseconds="$(CopyRetryDelayMilliseconds)"/>

and References.Identity resolves to the source identity, not the target identity. So if the source exists it will not copy.

To work around it, and in case in some other usages for this target need this functionality I added a custom beforebuild override in my .wdproj file:

<Target Name="BeforeBuild">
  <Message Text="Doing custom BeforeBuild" />
<Copy 
      SourceFiles="@(References->'%(FullPath)')" 
      DestinationFolder="$(_FullSourceWebDir)\Bin\" 
      ContinueOnError="true"
      SkipUnchangedFiles="true"
      Retries="$(CopyRetryCount)"
      RetryDelayMilliseconds="$(CopyRetryDelayMilliseconds)"/>
</Target>

Thursday, May 12, 2011

Workflow 4 Default types to designer initialization

Dependency Injection way overboard?

I've been reflectoring, googling, stackoverflowing for weeks and just now stumbled upon the attribute injector code that runs to give ForEachActivity and SequenceActivity a designer.

Why weren't these attributes placed on the classes themselves? I have no idea.

Point your reflector at System.Activities.Core.Presentation in %windir%\Microsoft.NET\Framework\(4 something)



It's in 



System.Activities.Core.Presentation.DesignerMetadata.Register();
//Sneak peak
{
  AttributeTableBuilder builder = new AttributeTableBuilder();
  builder.AddCustomAttributes(typeof(ActivityAction),
    new Attribute[] { new EditorReuseAttribute(false) });
  SequenceDesigner.RegisterMetadata(builder);
  ForEachDesigner.RegisterMetadata(builder);
}