Thursday, September 29, 2011

Microsoft is embracing extensibility... using Stackoverflow.com for forums, and uservoice for VS feedback!


Where are the MSDN forums?
We have decided to migrate our forums to stackoverflow.com in order to better build a community around Pex and Moles. Questions about Pex should be tagged with 'Pex' and Moles with 'Moles'...

Monday, September 19, 2011

Some F# early learning and reference

I'm translating my bulk code detector from c# to f#, to learn f#. It's a linqpad c# program that recurses a directory tree organizing code

  • by
    • highest line count 
    • highest line count by directory 
    • highest line count by base filename (the stuff before the .) 
  • includes 
    • non-whitespace count 
    • potential magic numbers count 
    • " count


//path returns string
let path :string= 
  let userPath=Util.ReadLine("SourceDirectory?",@"D:\projects\")
  let exists=System.IO.Directory.Exists(userPath)
  if not(exists) then //guard clause
    raise(DirectoryNotFoundException(userPath))
  userPath
  
let doTestFileExclude = false

//fileExclude= Func<string,bool> a=>
let fileExclude  (a:string):bool = 
  a.EndsWith("designer.cs",StringComparison.CurrentCultureIgnoreCase)||
  a.StartsWith("jquery-",StringComparison.CurrentCultureIgnoreCase)||
  a.StartsWith("AssemblyInfo");
  
let pathExclude (a:string) :bool =
  a.Contains(@"\Database\")||
  a.Contains("Service References")||
  a.Contains("Web References") ||
  a.Contains("PackageTmp") ||
  a.StartsWith(@"~\Web\Scripts\Mvc3")

//record, class, struct, or discriminated union?  
type  CountSettings = {
  Path: string
  Patterns: IEnumerable<string>
  FileExclude: string -> bool
  PathExclude: string-> bool
  }
//instance of above type
let currentSettings:CountSettings=  {
  Path=path
  Patterns=["*.cs";"*.js"]
  FileExclude=fileExclude
  PathExclude=pathExclude
  }

//demonstrating access modifier  
let private testFileExclude() =
  let testCases = ["test";"test.designer.cs";"test.Designer.cs"]
  let mapped = testCases |>
    List.map(fun (fn:string) ->
      (fn,currentSettings.FileExclude(fn))
    )
  mapped.Dump("testFileExclude done")
  
if doTestFileExclude then
  do testFileExclude()

//set cwd (not a functional call, imperative?)
System.Environment.CurrentDirectory=currentSettings.Path
//public ~IEnumerable<T> visitDir(string dir,T1 dirFilter, T2 patterns, T3 fileFilter)
let rec visitAll (dir:string) patterns=seq{
  for pattern in patterns do
    yield! Directory.EnumerateFiles(dir,pattern)
  for subdir in Directory.EnumerateDirectories(dir) do
    yield! visitAll subdir patterns
  }
  
visitAll currentSettings.Path currentSettings.Patterns 
  |> Seq.length 
  |> fun x->x.Dump("LengthAll")


let rec visitDir (dir:string) dirFilter patterns fileFilter=
  seq{
  for pattern in patterns do
    for file in Directory.EnumerateFiles(dir,pattern) do
      if not(fileFilter(file)) then
        yield file
  for subdir in Directory.EnumerateDirectories(dir) do
    if not(dirFilter(subdir)) then
      yield! visitDir subdir dirFilter patterns fileFilter
  }
  
let visitDirResult= 
  visitDir currentSettings.Path currentSettings.PathExclude
    currentSettings.Patterns
      currentSettings.FileExclude
visitDirResult |> Seq.length |> fun x->x.Dump("visitDirLength")
visitDirResult |> fun x ->x.Dump("visitDirResult")

//Extension method on string
type System.String with
  member x.Right(index) = x.Substring(x.Length - index)

Tuesday, September 6, 2011

Local NuGet Feed on network drive

This was so much simpler than I imagined. I followed this article from Hanselman.


  1. Get the NuGet.exe command line here. Put it in the %path% or somewhere.
  2. Create a directory for your package - I created mine on the network share directly
  3. on the command line in your new folder nuget.exe spec
    1. Depends on your nuget.exe being in the %path%
  4. edit any fields in the new Package.nuspec file.
  5. If you have assemblies
    1. Add a lib folder
      1. Add assemblies inside
  6. If you have other content
    1. Add a content folder
      1. Add files inside
  7. If you have transforms
    1. Add filename.transform inside the content folder
      1. For example web.config.transform
  8. nuget.exe pack package.nuspec
Package created!

Now add that location in your Vs2010  Tools->LibraryPackageManager->PackageManagerSettings
In Package sources add the source, and name it. TADA!

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