Thursday, May 30, 2013

Add License Comment to every C# file during Visual Studio Build

I have been working on an open-source project and wanted to add a license comment (like the one below) to every class file.  Additionally, I wanted to do this as a Visual Studio Build Event so that any new class files would automatically get updated.



//-----------------------------------------------------------------------
// <copyright file="CloneIntentsAttribute.cs" company="Copacetic Software">
// Copyright (c) Copacetic Software. 
// <author>Philip Pittle</author>
// <date>Wednesday, May 29, 2013 6:45:52 PM</date>
// Licensed under the Apache License, Version 2.0,
// you may not use this file except in compliance with one of the Licenses.
// 
// You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an 'AS IS' BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// </copyright>
//-----------------------------------------------------------------------

I ended up using a power shell script by Kishor Aher with modifications by Leniel Macaferi and with a few modifications I added myself:




param($target = "C:\MyProject\trunk", $companyname = "Copacetic Software") 
 
#[System.Globalization.CultureInfo] 
$ci = [System.Globalization.CultureInfo]::GetCurrentCulture
 
# Full date pattern with a given CultureInfo 
# Look here for available String date patterns: http://www.csharp-examples.net/string-format-datetime/ 
 
$date = (Get-Date).ToString("F", $ci); 
 
# Header template 
$header = 
"//----------------------------------------------------------------------- 
// <copyright file=""{0}"" company=""{1}""> 
// Copyright (c) {1}.   
// <author>Philip Pittle</author>  
// <date>{2}</date>  
// Licensed under the Apache License, Version 2.0, 
// you may not use this file except in compliance with one of the Licenses. 
//   
// You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 
// 
// Unless required by applicable law or agreed to in writing, software 
// distributed under the License is distributed on an 'AS IS' BASIS, 
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
// See the License for the specific language governing permissions and 
// limitations under the License. 
// </copyright>  
//-----------------------------------------------------------------------`r`n"
 
  function Write-Header ($file) 
  { 
    # Get the file content as as Array object that contains the file lines     
    $content = Get-Content $file 
    
    # Getting the content as a String 
    $contentAsString = $content | Out-String 
    
    # If content starts with //-- the skip it 
    if(!$contentAsString.StartsWith("//--"))
    {     
        # Splitting the file path and getting the leaf/last part, that is, the file name 
        $filename = Split-Path -Leaf $file 
        
        # $fileheader is assigned the value of $header with dynamic values passed as parameters after -f     
        $fileheader = $header -f $filename, $companyname, $date 
        
        # Writing the header to the file 
        Set-Content $file $fileheader -encoding UTF8 
        
        # Append the content to the file
        Add-Content $file $content     
    }
} 
 
#Filter files getting only .cs ones and exclude specific file extensions 
Get-ChildItem $target -Filter *.cs -Exclude TemporaryGeneratedFile*.cs, *.Designer.cs,T4MVC.cs,*.generated.cs,*.ModelUnbinder.cs -recurse | % `
{ 
    <# For each file on the $target directory that matches the filter, let's call the Write-Header function defined above passing the file as parameter #> 
    Write-Header $_.PSPath.Split(":", 3)[2] 
} 

In order to get run the script during a build phase, Visual Studio needs permissions to run power shell commands (http://stackoverflow.com/questions/5006619/call-powershell-script-in-post-built-with-parameters?rq=1).  Run the following batch script:

REM This Script Must Be Run As An Administrator

%SystemRoot%\SysWOW64\WindowsPowerShell\v1.0\powershell.exe "Set-ExecutionPolicy Unrestricted"
%SystemRoot%\System32\WindowsPowerShell\v1.0\powershell.exe "Set-ExecutionPolicy Unrestricted"

Then add the following to Visual Studio pre-build event:

powershell.exe -file "$(SolutionDir)\scripts\AddCopyrightToAllClasses.ps1" -target $(ProjectDir)
(In this case, I have saved the power shell script above as AddCopyrightToAllClasses.ps1 and saved it in a directory called scripts.  The scripts directory is in the solution directory (not the project directory).

I originally found the links to the power shell script on stackoverflow: http://stackoverflow.com/questions/12199409/inserting-copyright-notice-banner-in-all-source-code-files-in-visual-studio-2012

Monday, March 18, 2013

C# Object Composition - Removing Boilerplate Code

I've worked on numerous .NET projects that have been required to persist data and have usually ended up using a Repository pattern. Does anyone know of a good strategy for removing as much boilerplate code without sacrificing code base scalability?

Inheritance Stragegy

Because so much of the Repository code is boiler plate and needs to be repeated I normally create a base class to cover the basics like exception handling, logging and transaction support as well as a few basic CRUD methods:
public abstract class BaseRepository<T> where T : IEntity
{
    protected void ExecuteQuery(Action query)
    {
        //Do Transaction Support / Error Handling / Logging
        query();
    }       

    //CRUD Methods:
    public virtual T GetByID(int id){}
    public virtual IEnumerable<T> GetAll(int id){}
    public virtual void Add (T Entity){}
    public virtual void Update(T Entity){}
    public void Delete(T Entity){}
}
So this works well when I have simple domain, I can quickly create a DRY repository class for each entity. However, this starts to break down when the domain gets more complex. Lets say a new entity is introduced that does not allow updates. I can break up base classes and move the Update method into a different class:
public abstract class BaseRepositorySimple<T> where T : IEntity
{
    protected void ExecuteQuery(Action query);

    public virtual T GetByID(int id){}
    public virtual IEnumerable<T> GetAll(int id){}
    public virtual void Add (T entity){}
    public void Delete(T entity){}
}

public abstract class BaseRepositoryWithUpdate<T> :
    BaseRepositorySimple<T> where T : IEntity
{
     public virtual void Update(T entity){}
}
This solution does not scale well. Let's say I have several Entities that have a common method: public virtual void Archive(T entity){}
but some Entities that can be Archived can also be Updated, but others can't be Updated. So my Inheritance solution breaks down, I'd have to create two new base classes to deal with this scenario.

Compoisition Strategy

I've explored the Compositon pattern, but this seems to leave a lot of boiler plate code:
public class MyEntityRepository : IGetByID<MyEntity>, IArchive<MyEntity>
{
    private Archiver<MyEntity> _archiveWrapper;      
    private GetByIDRetriever<MyEntity> _getByIDWrapper;

    public MyEntityRepository()
    {
         //initialize wrappers (or pull them in
         //using Constructor Injection and DI)
    }

    public MyEntity GetByID(int id)
    {
         return _getByIDWrapper(id).GetByID(id);
    }

    public void Archive(MyEntity entity)
    {
         _archiveWrapper.Archive(entity)'
    }
} 
The MyEntityRepository is now loaded with boilerplate code. Is there a tool / pattern that I can use to automatically generate this?
If I could turn the MyEntityRepository into something like this, I think that would by far be ideal:
[Implement(Interface=typeof(IGetByID<MyEntity>), 
    Using = GetByIDRetriever<MyEntity>)]      
[Implement(Interface=typeof(IArchive<MyEntity>), 
    Using = Archiver<MyEntity>)
public class MyEntityRepository
{
    public MyEntityRepository()
    {
         //initialize wrappers (or pull them in
         //using Constructor Injection and DI)
    }
}

Aspect Orientated Programming

I looked into using an AOP framework for this, specifically PostSharp and their Composition Aspect, which looks like it should do the trick, but in order to use a Repository I'll have to call Post.Cast<>(), which adds a very odd smell to the code. Anyone know if there's a better way to use AOP to help get rid of the compositor boilerplate code?

Custom Code Generator

If all else fails, I suppose I could work at creating a Custom Code Generator Visual Studio plug in that could generate the boiler plate code into a partial code file. Is there already a tool out there that would do this?
[Implement(Interface=typeof(IGetByID<MyEntity>), 
    Using = GetByIDRetriever<MyEntity>)]      
[Implement(Interface=typeof(IArchive<MyEntity>), 
    Using = Archiver<MyEntity>)
public partial class MyEntityRepository
{
    public MyEntityRepository()
    {
         //initialize wrappers (or pull them in
         //using Constructor Injection and DI)
    }
} 

//Generated Class file
public partial class MyEntityRepository : IGetByID<MyEntity>, IArchive<MyEntity>
{
    private Archiver<MyEntity> _archiveWrapper;      
    private GetByIDRetriever<MyEntity> _getByIDWrapper;

    public MyEntity GetByID(int id)
    {
         return _getByIDWrapper(id).GetByID(id);
    }

    public void Archive(MyEntity entity)
    {
         _archiveWrapper.Archive(entity)'
    }
} 

Extension Methods

I have also tried experimenting with extension methods:
public static class GetByIDExtenions
{
     public T GetByID<T>(this IGetByID<T> repository, int id){ }        
}
However, this has two problems, a) I'd have to remember the namespace of the extension methods class and add it everywhere and b) the extension methods can't satisfy interface dependencies:
public interface IMyEntityRepository : IGetByID<MyEntity>{}
public class MyEntityRepository : IMyEntityRepository{}