Using Log4Net Wrapper Implemented by Castle Windsor Logging Library

by Indra 27. August 2012 03:29

I am using Castle Windsor for my dependency injection and AOP.

Castle also has Logging Facility implemented in Log4net.

The problem with facility or constructur injection: in some part of application Castle Container is not ready yet (Global.asax, installer or ControllerFactory when you want to have logging) so you have to roll your own Log4Net code.

Castle.Services.Logging.Log4netIntegration has Log4Net wrapper that we can use. The wrapper already handle IsDebugEnabled etc. we just use ILogger.Info, ILogger.Error, etc.)

 

simple usage: Just create an instance of Log4netFactory and create the implementation of Castle.Core.Logging.ILogger

 

Log4netFactory _log4NetFactory = new Log4netFactory();

ILogger logger = _log4NetFactory.Create(this.GetType());

 

Source code for Log4netLogger is available at Castle Project at GitHub

If you want to improve your logger performance you might want to read this link AOP With castle–Part 3-The first interceptor . This article show how to use dictionary as a cache to store your class loggers.

Tags:

Log4Net | Castle Windsor

Open Source ASP.NET Ajax Polls (for Umbraco and any ASP.NET 4.0 Web Application/Site)

by Indra 15. November 2011 00:10

Our company MAP Teams released Polls widget for Umbraco 4.7 at MapTeams Umbraco Polls Package. This project can be implemented in any ASP.NET Web Application/Site, not just Umbraco.

Source code available at http://mapteamspolls.codeplex.com/

This project is an extension from ClientSideAsp's Polls project. Thank you Ansar for sharing your project.

Selling point for this release:

  • Mustache Logicless Templating Engine for server side and client side. Reduce code duplication - easily change your html layout in one place without re-compiling.
  • Umbraco Package Automation using Ruby Rake. Want to extend our polls features for Umbraco? Just modify the code, run the build script to create your own package. 

Why Mustache/Nustache? Well at this time Templating Engine from Microsoft and jQuery was cancelled; researching the alternatives, I found that Mustache templating is implemented in many languages.

Tags: , ,

Projects

Ruby Rake Files And Directories manipulation tasks

by Indra 10. November 2011 05:54

These are file and directory manipulation tasks that I use during continuous integration process at MAP Teams(a really cool .NET shop in Jakarta, Indonesia).

List of tasks:
  1. Change Inheritance of some classes before compiling the project(solution)
  2. Copy all files named "copy of app.config" to "app.config" or web.config before compiling solution.
  3. Change version number in assemblyInfo file before committing source code back to repository.
  4. Deleting and creating temp directory hierarchy.
  5. Will be added later.

1. Change Inheritance of some classes before compiling the project(solution)

task :Change_Class_Inheritance do

   classFiles =  File.join(LOC_WORKING_DIRECTORY,"another\\folders/hierarchy","../foldersA/folderB\\MapTeamsPolls/Admin*.aspx.cs")
	# glob with the pattern for  files with " Admin*.aspx.cs" in the directory location
	fileCollection = Dir[classFiles] 
	fileCollection.each do|sourceFile|
		#read file content to string variable
		text = File.read( sourceFile)
		
		#change the line matching the pattern
		text = text.gsub(/(^\s*public partial class .*:\s*)(.*)/, '\1UmbracoEnsuredPage')		
		
		#write the modified content back to file
		File.open(sourceFile, 'w') { |f| f.write(text) }
			
	end
End
    
(Back to index.)

2. Copy all files named "copy of app.config" to "app.config" or web.config before compiling solution.

def CommonUtils.rename_config_files(sourcePath)
	
    #replace backslash to forward slash; glob doesn't work with backslash!!!
    sourceFolder = sourcePath.gsub(/\\/, '/')
    pattern1 = sourceFolder+'/**/copy of *.config'   
    pattern2 = sourceFolder+'/**/*copy.config'
	
    #search recursive directory below solution folder; search for "copy of " files ; remove the "copy of "
    Dir[pattern1, pattern2].each { |configFile| 		
	    FileUtils.cp(configFile, configFile.gsub(/copy of | - Copy/i,'') , :verbose=>true )
    }
end
    
(Back to index.)

3. Change version number in assemblyInfo file before committing source code back to repository

### sourceFolder = project folder containing assemblyInfo; multiple folder
### "1.2.4.5"
def CommonUtils.update_assemblyInfo(sourceFolder, version)

	sourceFolder = sourceFolder.gsub(/\\/, '/') #replace backslash ke forward slash; glob tidak bekerja kalau pakai backslash!!!
	
	pattern1 = sourceFolder+"/**/Properties/AssemblyInfo.cs"
	
	fileCollection = Dir[pattern1]
	
	raise "No Assembly info found in (#{sourceFolder}) ; please check folder" if fileCollection.count == 0
	
	fileCollection.each { |configFile| 	
		text = File.read(configFile)
		newContent = text.gsub!(/Assembly(|File)Version\(\".*\"\)/, "Assembly\\1Version(\"#{version}\")")
	 
		File.open(configFile, 'w') { |f| f.write(newContent) }
	}
end
    
(Back to index.)

4. Deleting and creating temp directory hierarchy.

#target can be folders hierarchy (d:\\folderA/folderB\\folderC/folderD)
def RecreateEmptyFolder(target)
    FileUtils.rm_rf(target, :verbose=>true) if (Dir[target] != [] and Dir[target] != nil )
		
    #make sure no other process is holding the folder
    #sometimes will fail as if rm_rf still not finished while mkdir_p is working
    sleep 3 
    FileUtils.mkdir_p target , :verbose=>true
end
    
(Back to index.)

Tags: ,

Continuous Integration | Snippets | Ruby

How To Execute InstallUtil With WIX 3.5

by Indra 12. September 2011 04:31

I need to execute InstallUtil.exe at the end of a MSI installation created using WIX.

At that moment this link is down (How to Invoke InstallUtil.exe in WiX Custom Action to Call Your Managed Installer Class).

I found out that what I need was Custom Action Type 34 (running an exe with a working directory) from these threads:

These are the code snippets incase the first link is down again.

 

<!-- create custom action -->
<CustomAction Id="AfterCopyingFiles" Directory="DirectoryID_Where_InstallUtil_Is_Copied"
        ExeCommand="[DirectoryID_Where_InstallUtil_Is_Copied]installutil.exe File_Containing_RunInstaller_Attribute.exe" Return="check" Impersonate="yes" Execute="deferred" />

<CustomAction Id="ForUninstall" Directory="DirectoryID_Where_InstallUtil_Is_Copied"
        ExeCommand="[DirectoryID_Where_InstallUtil_Is_Copied]installutil.exe /u File_Containing_RunInstaller_Attribute.exe" Return="check" Impersonate="yes" Execute="immediate" />

<!-- set when custom action will execute -->
<InstallExecuteSequence>
    <!--install-->
    <Custom Action="AfterCopyingFiles" After="InstallFiles">NOT Installed</Custom>
  
    <!--uninstall-->
    <Custom Action="ForUninstall" Before="RemoveFiles">REMOVE="ALL"</Custom>
</InstallExecuteSequence>

 

After reading Chapter 5 from WIX A Developers Guide to Windows Installer I found out 2 more ways to trigger an executable during installation:

  • Custom Action Type 2: using Binary element for storing executable in MSI.
  • Custom Action Type 18: using File element for copying the executable first to the target machine.

code snippet:

<CustomAction Id="CustomActionType2"
   BinaryKey="BinaryElementId_For_The_Executable"
   ExeCommand=""
   Execute="commit"
   Return="ignore" />

<CustomAction Id="CustomActionType18"
   FileKey="FileElementId_For_The_Executable"
   ExeCommand=""
   Execute="commit"
   Return="ignore" />

Tags: ,

Continuous Integration | WIX

SVN Revision Labeller Does Not Work With CruiseControl.NET Beta 1.6

by Indra 19. January 2011 05:53

It's time to upgrade our Continuous Integration platform; I am updating CCNET 1.5 to CCNET 1.6 beta. Configuration Preprocessor with Conditional logic is awesome, I can refactor our distributed build system better with this.

The first error message I got after running the beta version:

 

[CCNet Server:ERROR] INTERNAL ERROR: Could not evaluate expression 'major}.{mino r}.{build}.{revision'
Reason: Syntax error
 ----------


The svnrevisionlabeller plugin from http://code.google.com/p/svnrevisionlabeller/ is not compatible with CCNET beta 1.6.

My quick fix is to edit and recompile the SVN Revision Labeller plugin. You can download the compiled dll here: ccnet.SvnRevisionLabeller.plugin.dll.zip (4.89 kb) and copy to the CCNET installation folder (WARNING! you must change the labeller pattern using '(' and ')' instead of '{' and '}' ).
or follow my steps to recompile:

  • 1. Download the labeller plugin source code.
  • 2. Copy 2 dlls from CCNET 1.6 installation folder to source code's Lib folder :
  •  
    • ThoughtWorks.CruiseControl.Core.dll
    • ThoughtWorks.CruiseControl.Remote.dll
  • 3. Change the regex pattern from { } to ( ) . you can use other pattern. 
    Where to edit the regex token
  • 4. Change your Labeller section in CCNET configuration to use the new token.

This is just my own solution; I haven't contacted the developer for this plugin.

Tags: ,

Continuous Integration

BlogEngine RC 2.0 and SyntaxHighlighter 3.0.83 Line Wrap Problem

by Indra 20. December 2010 18:45

BlogEngine RC 2.0 comes with SyntaxHighlighter 3.0.83; Too bad the horizontal line wrap does not work, first I thought it was because I am using Themes for BE 1.5.

I found this bug report on SyntaxHighlighter: horizontal-line-wrapping-doesnt-work.

I do not have time to implement the solutions there, so I use SyntaxHighlighter 2.1 instead.

Just copy and paste the files from scripts and styles folder to BlogEngine's.

Tags:

Common MSBuild Command Line

by Indra 14. December 2010 21:34

These are collection of command line MSBuild that I Use for building and deploying my .Net projects. I use Rake for calling these commands

MSBUILD's parameters are case sensitive!

Updated Dec 17 2011: use the correct OutputPath for console app instead of outdir.

Build whole solution:

Just build whole solution as if pressing ctrl+shift+b from visual studio, does not care where to put the output. Use this when someone commit to trunk to see if the last commited code compiled successfully

"C:\msbuild directory\MSBuild.exe" "D:\path\to\solution\folder\Solution.sln" /p:configuration="Release" /target:Clean;Build

Build Console Application:


Difference with Web App: Use the OutputPath property instead of outdir! DO NOT END the directory path with backslash "\"
"C:\msbuild directory\MSBuild.exe" "D:\path\to\project\folder\ProjectFile.csproj" /p:configuration="Release" /target:Clean;Build /p:OutputPath="c:\path\to\output\bin_NO_BACKSLASH"

Build Web Application Project or Web Service Project:

Output directory has to end with '\'.

Observere output for the bin folder.

"C:\msbuild directory\MSBuild.exe" "D:\path\to\project\folder\ProjectFile.csproj" /p:configuration="Release" /target:ResolveReferences;_CopyWebApplication /p:webprojectoutputdir="c:\\path\\to\\output\\" /p:outdir="c:\\path\\to\\output\\bin\\" 
Use double-backslash "\\" or forward slash"/" if you use ' " ' quotes(directory with spaces) for WebProjectOutputDir and OutDir property.

Build Web Site Project Using ASPNET_COMPILER

Use ASPNET_COMPILER.EXE to precompile Web Site Project where no project file can be found (can also be used for ASMX Web Service)
you have to input the /IIS_ApplicationName parameter even though you are not publishing it to IIS!

"C:aspnet_compiler directory\aspnet_compiler.exe"  -f -v /IIS_ApplicationName -p c:\source_folder c:\output_folder

LC.EXE and SGEN.EXE

If you do not install .NET SDK on the build machine, you have to add these parameters so MSBUILD can find the LC.EXE and SGEN.EXE

/p:LCToolPath="c:\folder\where\LC_is_located"   /p:SGenToolPath="c:\folder\where\SGEN_is_located"

Tags: ,