Current Project Technologies

I’ve explored and started/continued using a lot of stuff on my new project.  A coworker of mine started me out on Inversion of Control and ORM tools and it’s gotten more awesome from there.  Here is a concise list:

  • Inversion of Control & Dependency Injection: Castle Windsor. I switched from StructureMap.  Everything is handled through interfaces and is decoupled.  I can mock anything in unit tests.
  • ORM: NHibernate with Fluent NHibernate auto mappings installed with this NHibernate Facility.  I don’t write SQL, HQL, etc. I just use Linq to get what I want unless it has to be optimized.
  • Database: SQLite with Linq provider. Very easy to get a database up and running.
  • Automatic Transaction Scoping: Castle AutoTx Facility.  No more boilerplate transaction code.
  • GUI: Windows Presentation Foundation implementing the Model-View-ViewModel pattern.  You have to be strict to do it right but when you do it makes things a lot easier.  My code-behind rarely has code, everything is in the Xaml.
  • Commanding: Routed Commands.  Bind commands to buttons, etc. and everything is handled for you.
  • Easy Parallelism: Task Parallel Library.  I’m getting used to chaining long running things with Tasks.  Exceptions and return values are handled the right way.  I started looking at Reactive Extensions to query events and Observables.
  • Dependency Management: NuGet.  No more lib folder or dlls in your repository.  We now host our own feed so we can share code and manage dependencies.
  • Installer Framework: Windows Installer Xml. It has a steep learning curve but it’s the best tool out there to build installers.  Started by Microsoft people then open-sourced.
  • Logging: log4net.  I will hurt you if you write your own logger.
  • Object Mocking: Rhino Mocks.  I can test just what I want keeping tests small and easy to maintain.
  • Unit Testing: NUnit.  Duh.
  • Continuous Testing: NCrunch. It’s awesome to watch tests pass and fail in Visual Studio as you write code.
  • Continuous Integration: Jenkins. It builds everything including the installer.
  • Build Tool: NAnt with NAntContrib for WiX tasks.  Always have a build process.
  • Generate Fake Data: Faker, generates lorem epsum; good looking names, emails, etc. No more User1, User2, email@someaddress.org.
  • Source Control: Git.  It has a steep learning curve especially if you’re switching from a centralized tool like Subversion but it’s worth it.
  • Configuration: Using Configuration Sections to organize settings and Configuration Property Attributes to set defaults, etc.  Don’t repeat the name of the property, use ExtractPropertyName so you can refactor your configurations.
  • Configuration Validation: Using Validation Attributes and writing Validators to validate hostnames, file paths to files that must exist, enums, etc. in configuration files.
  • Storage: Isolated Storage.  Nothing is stored alongside the application.  Easy access without any permissions errors.
  • Documentation: GhostDoc to help generate comments.  I’m want to try SandCastle to generate documentation when I get time.
  • Get more done in VS: ReSharper.  I can’t code without it, seriously.  It saves so much time and makes your code cleaner.
  • Code Style: StyleCop with some of the rules relaxed.
Tagged with:
Posted in .Net, Inversion of Control, Unit Testing, WiX, WPF

Hosting a NuGet Feed on IIS

These instructions are great.  The only snag I ran into was that you need to install the WebDAV extension for IIS.  If you’re running IIS 7.5 (Server 2008 R2) you just have to enable it under the Web Server role.  If you’re running IIS 7 (Server 2008) it’s available here.  The more recent versions of IIS don’t come with WebDAV (the ‘put’ verb) support which results in ‘405 method not allowed’ errors.  You have to configure the rules for WebDAV after installing it or you’ll get ‘403 forbidden’ errors.

Tagged with:
Posted in .Net

Continuous Testing with NCrunch

NCrunch is awesome.

  • It runs all your tests in the background whenever you make a change.
  • It indicates which lines are covered in tests and if they pass.

Go get it.  It’s free.

Tagged with: , ,
Posted in .Net, Unit Testing

Fluent NHibernate, Castle Windsor, and Automatic Transactions

Getting things hooked up

I recently switched out StructreMap for Castle Windsor as the Inversion of Control container on my new project. The main reason for this was to get automatic transactions via Castle’s AutoTx Facility. This means all I have to do in my model is add the TransactionAttribute to any method I need to be transactional. Any sessions injected via the usual Windsor way (Func<ISession> or SessionManager) are automatically flushed and disposed of. It really reduced the amount of boilerplate code that needs to be written. This was a good resource.

Most of my FluentNHibernate installer.

public class FluentNHibernateInstaller : INHibernateInstaller
{
    public FluentConfiguration BuildFluent()
    {
        return Fluently.Configure()
                .Database(SQLiteConfiguration.Standard.UsingFile(filePath))
                .Mappings(m => m.AutoMappings.Add(AutoMap.AssemblyOf(new IbacDataConfiguration())))
                .ExposeConfiguration(o =>
                 {
                     if (databaseType == DatabaseType.SQLLiteFileBased)
                     {
                       if (!File.Exists(filePath))
                           BuildSchema(o);
                       else
                           UpdateSchema(o);
                     }
                     else if(databaseType == DatabaseType.SQLLiteInMemory)
                           BuildSchmea(o);
                     else if(databaseType == DatabaseType.SQLServer2005)
                           UpdateSchema(o);
                 });
    }

    private static void BuildSchmea(Configuration cfg)
    {
        SchemaUpdateLog.InfoFormat("-- Create script, circa {0}", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));
        new SchemaExport(cfg).Execute(SchemaUpdateLog.Info, true, false);
    }

    private static void UpdateSchema(Configuration cfg)
    {
        SchemaUpdateLog.InfoFormat("Update script, circa {0}",
                        DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));
        new SchemaUpdate(cfg).Execute(SchemaUpdateLog.Info, true);
    }
}

Here’s what I use to bootstrap my Dao.Hibernate project. A bit of a snag? Make sure your AutoTxFacility is registered before anything that might be transactional. Same thing for the Factory Support Facility. It has to come before anything that might be created with a factory.

public static void Bootstrap(IWindsorContainer container)
{
    container.AddFacility<AutoTxFacility>();
    container.AddFacility<FactorySupportFacility>();
    container.Register(Component.For<INHibernateInstaller>().ImplementedBy<FluentNHibernateInstaller>());
    container.AddFacility<NHibernateFacility>(
         o => o.DefaultLifeStyle = DefaultSessionLifeStyleOption.SessionTransient);
     container.Register(Component.For<ISomeDao>().ImplementedBy<SomeDao>());
}

Then in my actual application project:

IoC = new WindsorContainer();
NHibernateDao.Bootstrap(IoC);
IoC.Register(Component.For<ISomeModel>().ImplementedBy<SomeModel>().LifestyleSingleton());

The layers

  1. Project.Domain – contains all my domain objects, no references, that’s it
  2. Project.Dao – Interfaces for the daos
  3. Project.Dao.Hibernate – implemented daos, FluentNHibernateInstaller, bootstrapping code, and generated sessions (per call)
  4. Project.App – Everything else
    1. Models (singletons) – The models with business logic and transactions
    2. ViewModels (one per view) – Mapping to what’s displayed
    3. Views – user controls, windows, etc.

A typical dao implementation:

public class SomeDao : ISomeDao
{
    private static readonly ILog Log = LogManager.GetLogger(
        MethodBase.GetCurrentMethod().DeclaringType);
    private readonly Func<ISession> _session;

    public SomeDao(Func<ISession> session)
    {
        _session = session;
    }

    #region ISomeDao Members

    public virtual IEnumerable<IIbacData> GetAllSomeDomainObject()
    {
        return _session().CreateCriteria<SomeDomainObject>().List<SomeDomainObject>();
    }
...
}

A typical Model:

public class SomeDomainObjectModel : ModelBase, ISomeDomainObjectModel
{
    #region ISomeDomainObjectModel Members

    public virtual IEnumerable<ISomeDomainObject> GetAllData()
    {
        return IoC.Resolve<ISomeDao>().GetAllSomeDomainObject();
    }

    [Transaction]
    public virtual void SaveNew(ISomeDomainObject data)
    {
        IoC.Resolve<ISomeDao>().SaveNew(data);
        RaiseNewData(data);
    }
...
}
Tagged with: , , , , ,
Posted in .Net, Inversion of Control

Easy to Use Temporary File and Directories

I have to create a lot of temporary files in a project and I was sick of the usual way of doing things.  It was too verbose and prone to errors.  I created temporary disposable file and directory objects that are very easy to use. The files are created in Isolated Storage if no parent path is provided. I’ve never used Isolated Storage but it seems like a good place to create temporary files since it can be kept separate from other applications and users. You don’t have to clutter up the usual temp directory or worry about write permissions to your application’s working directory.

using (var directory = new TemporaryDirectory(optionalPath))
{
    //use directory.DirectoryPath to do stuff
}
using (var file = new TemporaryFile(optionalDirectory, optionalExtension)
{
    //use file.FilePath to do stuff
}
    public class TemporaryFile : IDisposable
    {
        public TemporaryFile() :
            this(null, ".temp")
        {
        }

        protected TemporaryFile(string directory, string extension)
        {
            var filename = String.Format("{0}.{1}", Guid.NewGuid(), extension);

            if (String.IsNullOrEmpty(directory))
            {
                var store = IsolatedStorageFile.GetUserStoreForAssembly();
                using(var stream = store.CreateFile(filename))
                {
                    FilePath =
                        stream.GetType().GetField("m_FullPath", BindingFlags.Instance | BindingFlags.NonPublic).GetValue
                            (stream).ToString();
                }
            }
            else
            {
                FilePath = Path.Combine(directory, filename);
                using (File.Create(FilePath))
                {
                }
            }
        }

        public string FilePath { get; private set; }

        #region IDisposable Members

        public void Dispose()
        {
            Delete();
            GC.SuppressFinalize(this);
        }

        #endregion

        ~TemporaryFile()
        {
            Delete();
        }

        private void Create(string path)
        {
            FilePath = path;
            using (File.Create(FilePath))
            {
            }
        }

        private void Delete()
        {
            if (FilePath == null) return;
            File.Delete(FilePath);
            FilePath = null;
        }
    }
    public class TemporaryDirectory : IDisposable
    {
        public TemporaryDirectory(string path)
        {
            var directoryName = Guid.NewGuid().ToString();

            if(String.IsNullOrEmpty(path))
            {
                var store = IsolatedStorageFile.GetUserStoreForAssembly();
                store.CreateDirectory(directoryName);
                var storePath =
                    store.GetType().GetField("m_RootDir", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(
                        store).
                        ToString();
                DirectoryPath = Path.Combine(storePath, directoryName);
            }
            else
            {
                DirectoryPath = Path.Combine(path, directoryName);
                Directory.CreateDirectory(DirectoryPath);
            }
        }

        public TemporaryDirectory() : this (null)
        {

        }

        public string DirectoryPath { get; private set; }

        #region IDisposable Members

        public void Dispose()
        {
            Delete();
            GC.SuppressFinalize(this);
        }

        #endregion

        ~TemporaryDirectory()
        {
            Delete();
        }

        private void Delete()
        {
            if (DirectoryPath == null) return;
            Directory.Delete(DirectoryPath, true);
            DirectoryPath = null;
        }
    }
Tagged with: , ,
Posted in .Net

Data Virtualization with WPF

Ben Stollnitz wrote a great post about how to get data virtualization working in WPF. It’s not baked in (yet) but his libraries and code make it easy. My biggest snag was having the width of my grid view set to automatic which forced the implicit loading of all the items in the collection. He compares two implementations. I started using the latter and it has worked out great so far.

Tagged with: ,
Posted in .Net, WPF

Backing up Jenkins with PowerShell

We’ve slowly adopted Jenkins for most of our software products.  We’re officially up to 20 projects being built and/or deployed by Jenkins.  All those jobs represent a lot of work and I’d hate to lose them.  Thanks to this stackoverflow post for showing me the right robocopy syntax.  I tried using xcopy but its exclude option isn’t honored while recursing.  This meant that the entire workspace was being copied.  Not so with robocopy!

robocopy C:\.hudson C:\Backups\jenkins_home /ZB /E /NP /R:1 /W:5 /TEE /XD workspace
Tagged with:
Posted in Jenkins, PowerShell

Backing up Nexus with PowerShell

We use Nexus to manage all of our artifacts and their storage.  It needs backed up as well!  The two critical pieces that need to be backed up are Nexus’s configuration and the hosted repositories.  No need in backing up your proxy repositories or index cache.

Backing up Nexus’s Configuration

The PowerShell Community Extensions are needed again.

Import-Module Pscx
$filename = "C:\Backups\nexus_config\nexus_config_" + (Get-Date -Format 'yyyy-MM-dd_HH-mm-ss') + ".zip"
Write-Zip -level 9 -IncludeEmptyDirectories -Path C:\sonatype-work\nexus\conf\* -OutputPath $filename

Backing up Nexus’s Hosted Repositories

Copy-Item C:\sonatype-work\nexus\storage\* "C:\Backups\nexus_storage" -Force -Recurse -Verbose
Tagged with:
Posted in Nexus, PowerShell

Backing up Redmine with PowerShell

So you’ve set up Redmine and your team is actually using it, congratulations! But what if that server went down, melted, or caught fire? The good news is that Redmine is just comprised really of two (or three) parts: its database, the files your users have uploaded, and optionally the plugins you’ve enabled.  These PowerShell scripts run every night to back everything up.

Backing up Redmine’s database

Backing up Redmine’s database is as easy as calling mysqldump.  I opted to encrypt the backups so they can be moved to another network share safely.  You’ll need Gzip for Windows and openssl.

$filename = "C:\Backups\redmine_database\redmine_backup_" + (Get-Date -Format 'yyyy-MM-dd_HH-mm-ss') + ".gz"
& "C:\Program Files\BitNami Redmine Stack\mysql\bin\mysqldump.exe" -u root -pmysql_password --all-databases | & "C:\Program Files (x86)\GnuWin32\bin\gzip.exe" > $filename
openssl enc -aes-256-cbc -salt -in $filename -out $filename".enc" -pass pass:password
Remove-Item $filename

Backing up Redmine’s Files

Redmine’s files are zipped up and encrypted.  I went a little over the top by creating a new zip file each day and only keeping the last seven days.  Everything is encrypted again and you’ll need the PowerShell Community Extensions to get the Write-Zip Cmdlet.

Import-Module Pscx
$deleteBefore = (Get-Date).AddDays(-7) $files = Get-ChildItem C:\Backups\redmine_files\ -Include *.enc | Where {$_.LastWriteTime -le $deleteBefore}
foreach($file in $files) { Remove-Item $file.FullName }
$filename = "C:\Backups\redmine_files\redmine_files_" + (Get-Date -Format 'yyyy-MM-dd_HH-mm-ss') + ".zip"
Write-Zip -level 9 -IncludeEmptyDirectories -Path 'C:\Program Files\BitNami Redmine Stack\apps\redmine\files\*' -OutputPath $filename
openssl enc -aes-256-cbc -salt -in $filename -out $filename".enc" -pass pass:password
Remove-Item $filename

Running PowerShell Scripts as a Task

Just call the PowerShell executable with the -File option and the path to your script.

Tagged with:
Posted in PowerShell, Redmine

Convert OVF VM to VMWare Fusion with OVFTool

Sometimes it won’t work. VM hardware might not be recognized, etc. You can still convert it using the ovftool. Just specify the undocumented –lax option which turns errors into warnings.

ovftool --lax source.ova target.vmx
Tagged with: , ,
Posted in Virtualization
Is this your new site? Log in to activate admin features and dismiss this message
Log In