Humblecoder

Apprentice unit tester, expert rambler

Archive for the ‘DirLinker’ tag

Directory Linker 2.1 – XP Support

with one comment

Today I have pushed new binaries to CodePlex for DirLinker.  This new release brings support for folder links in Windows XP/2003.  It is not able to create file links, this is because of the limitations in reparse points in earlier versions of Windows.

This is something I didn’t think I would do but after releasing Dirlinker 2 on Codeplex, a ticket was raised in the bug tracker because it was failing on XP and I was chatting to a friend on IM about it who basically said “Well why doesn’t it?”.  The main reason was because the API call for creating symbolic links is only available in Vista and later.  XP does have an equivalent but the behaviour of the links they create is subtly different.  In XP they are Reparse Points where as in Vista+ they are hard links (similar to *nix), I will go in to the difference in a future post.

It turns out that with a little help from a CodeProject article, it took less than an hour to put in and test, so it made it in.  I am definitely parking this to new features now.  Only bug fixes will be added from now on.

VN:F [1.9.3_1094]
Rating: 0.0/5 (0 votes cast)

Written by Will

May 5th, 2010 at 7:23 am

Directory Linker 2

with 2 comments

After literally months of procrastination Directory Linker 2 is finally in state that I’m not too ashamed of.  So today I have posted up new binaries on Codeplex.

What’s New?

  • Undo Support  If the process of moving and deleting a folder before creating a link at the same location failed, you could end up with some files in the new location, some in old and two partial directory structures.  If this happens now DirLinker will offer to put the original folder back how it was.

    If you’re using the just delete option and it fails, undo can not undelete any files but it will put back any folders it deleted.

  • File Links – It can now create symbolic links for files as well as directories.  You don’t have to do anything different, just select a file in the link location or the link to field.  There has been a small change to the UI to allow you to browse for files aswell as folders.

    In a future post I’m going to talk about the difference between symbolic links and shortcuts.  But for now the important difference is the application opening file doesn’t know the file is only a link when using symbolic links.

  • Progress Window Changes – The progress window has been slightly overhaul and now keeps a list of everything it has done.  So if it does fail or something goes wrong, you can work out exactly what it’s done.

Progress Window

With these features I’m planning on parking Directory Linker development, I will of course fix any bugs that may come up but I can’t see any new features being added.

Enjoy!

PS, If you have no idea what Directory Linker is, this is a good place to start.

VN:F [1.9.3_1094]
Rating: 0.0/5 (0 votes cast)

Written by Will

May 3rd, 2010 at 8:14 am

Detangling Service Locator From Dependency Injection

with 5 comments

I’m sure like many exploring Dependency Injection (DI) for the first time the biggest problem I had, was how to rid the world of those pesky little new statements.  The first application I tried to use DI with in anger was DirLinker.  I had no prior knowledge of any of the DI frameworks and started looking at patterns that would help me remove all the new statements.  Unfortunately, I hit up on service locator and the rest is a mess history.  I ended up with code the looks like the following inside DirLinker:

IFile aFile = ClassFactory.CreateInstance<IFile>();
aFile.SetFile(file);

There is a couple of things that bother me about this.  First is the static, I’m not a fan of statics at all, infact, I hate them.  Next is the SetFile call, for any meaningful work to be done with this class you need to pass in a filename and it should be a constructor argument.  In all fairness the SetFile problem is more to do with the limitations of my roll your own DI framework than anything else.

In spite of my niggling doubts, it worked so I left it alone.  Fast forward to last week when I came across a blog post entitled Service Locator is an Anti-Pattern.  This confirmed my initial discomfort and highlighted a problem I hadn’t thought of, namely that the class doesn’t advertise its dependencies.  Very bad for reuse.

Factories

As the blog post suggests a better way of doing this would have been to use factories so lets go over a couple of examples on how this could be achieved. 

Virtual Instance Methods

This is a method I would use when trying to a create a seam in legacy code to inject a dependency for unit testing.  To do this you create a virtual method on the class that needs to create the object. In the unit test inherit from the class under test and override the factory method to return your mock or stub.  For example:

public class FileConsumer
{
    protected virtual IFile GetFile(String filename)
    {
        return new FileImp(filename);
    }

    public void DoSomething()
    {
        IFile fileA = GetFile("test.txt");
        IFile fileB = GetFile("test2.txt");
        //uses files
    }
}

[TestFixture]
public class FileConsumerTests : FileConsumer
{
    protected override IFile GetFile(string filename)
    {
        return new FileMock(filename);
    }

    [Test]
    public void DosomethingTest()
    {
        //Code to perform test
    }
}

This is good because it’s clear to any maintainer what the dependency is and where it is coming from. 

Abstraction Factory Pattern

This would loudly and proudly advertise the dependency on the ability to create IFile objects.  It works by creating a class with methods solely responsible for creating IFile objects and then taking this as dependency for your class.  For example:

public interface IFileFactory
{
    IFile CreateFile(String filename);
}

public class FileFactory : IFileFactory
{
    public IFile CreateFile(string filename)
    {
        return new FileImp(filename);
    }
}

public class FileConsumer
{
    IFileFactory _fileFactory;

    public FileConsumer(IFileFactory fileFactory)
    {

        _fileFactory = fileFactory;
    }

    public void DoSomething()
    {
        IFile fileA = _fileFactory.CreateFile("test.txt");
        IFile fileB = _fileFactory.CreateFile("test.txt");
        //uses files
    }
}

This is the pattern recommended by the blog post and it covers all the things I don’t like about Service Locator.  But I think we could take advantage of some of C#’s language features and the fact we are creating objects via a container to achieve something similar but with less code.

Delegate Factories

Before I go into this a little disclaimer, this is totally and utterly inspired by Autofac’s wonderful generated delegate factory functionality, you can read more about it here.

OK, honesty out of way lets look at what the container knows and what it does.  The DI container knows what Interfaces should map on to what concrete types and it has the ability to resolve constructor arguments for types that it knows about.  This is just a generic version of a factory so it makes sense to take advantage of it.

One way would be to use Func<TResult>() (and its friends).  If the class being constructed requires a constructor parameter of Func<TResult> where TResult is the required interface, the container could generate an appropriate delegate at runtime and pass it in.  For example:

   public class FileConsumer
   {
       Func<IFile> _fileFactory;

       public FileConsumer(Func<IFile> fileFactory)
       {

           _fileFactory = fileFactory;
       }

       public void DoSomething()
       {
           IFile fileA = _fileFactory();
           IFile fileB = _fileFactory();

           //uses fileA
       }
   }

This would require a slight modification to the container and could be extended by the use of Func<T, Tn, TResult>(T value, Tn valuen).  The container would match the parameters to a suitable constructor. 

This is quite a powerful and time saving concept but I don’t like the vagueness of Func<TResult>(), it’s not as expressive as it could be.  So the method I have chosen for DirLinker is to use strongly typed delegates and generate them at runtime from the container.   It works in the same manner only you declare the delegate up front and pass them in as an argument.  This, also, requires a bit of configuration but the pay off is worth it.  I have started work on the implementation for DirLinker so this example is taken directly from the unit tests and can be found here

interface ITestClassWithDelegateFactory { ITestClassFactory Factory { get; set; } }
delegate ITestClass ITestClassFactory();

class TestClassWithDelegateFactory : ITestClassWithDelegateFactory
{
     public ITestClassFactory Factory { get; set; }
     public TestClassWithDelegateFactory(ITestClassFactory delegateFactory)
     {
         Factory = delegateFactory;
     }
}

[Test]
public void ManufactureType_Type_delegate_factory_manufactures_correct_type()
{
	IClassFactory testClassFactory = new ClassFactory();

	testClassFactory.RegisterType<ITestClass, TestClass>()
                .WithFactory<ITestClassFactory>();

	testClassFactory.RegisterType<ITestClassWithDelegateFactory, TestClassWithDelegateFactory>();

 	ITestClassWithDelegateFactory manufacturedType =
			testClassFactory.ManufactureType<ITestClassWithDelegateFactory>();
	ITestClass instance = manufacturedType.Factory();

	Assert.IsInstanceOf(typeof(TestClass), instance);

}

Admittedly there is quite a lot going on here but the main points are we registered a type and factory in a strongly typed manner with the container.  Then pull it out and use it to create an instance of a different type.  I am going to cover this in quite some detail along with the how to create strongly typed delegates at runtime in my next post.

VN:F [1.9.3_1094]
Rating: 0.0/5 (0 votes cast)

Written by Will

February 9th, 2010 at 7:42 am

Posted in .NET, C#, DirLinker, Unit testing

Tagged with , ,

Why DirLinker Doesn’t Support XP

without comments

I posted up the Directory Linker CodePlex project a little over 2 weeks ago and it has clocked up a reasonable 103 downloads in that time.  Last night I was glancing over where the traffic came from on the stats page and a lot of referrals have come from this review site, they state that:

The app works on Windows 7 and Vista only, support for Windows XP is planned in the near future.

This is incorrect and maybe I should have been more clear that Directory Linker will not support XP unless there is some overwhelming outcry for it or someone else does it.

Why?

First for selfish reasons, I don’t use a machine that has XP installed anymore, furthermore, I would encourage anyone on XP to upgrade for security if nothing else.  At the end of the day, I created this tool for my use and I don’t use XP.

The second reason is technical, without going to far in, symbolic directory links have been in NTFS for quite a while but only got ‘first class’ support by the OS recently.  Previous to Vista they were called Junction Points and had all kinds of weird side effects (more details here).  Also, the API calls used by Directory Linker to create the symobolic link is only supported by Vista and above.  It is technically possible to do the same for XP and it is not difficult but Directory Linker simply doesn’t do it.

I hope that clears things up, also if you find a download link for Director Linker that links to SoftSea in anyway please do not use it.  If you’re not a programmer it’s safe to stop reading now.

Fork You!

Well, I rather you didn’t.  I will happily accept any patch that is submitted to the project to do this.  To help you out here is a quick overview on how to do  it.

  1. Locate FolderImp.cs and make the CreateLinkToFolderAt method virtual.
  2. Create a new class that inherits from FolderImp and name it to show it is for XP.
  3. Override only the CreateLinkToFolderAt and add the code to create a link in XP (Tip: start at DeviceIoControl).
  4. Open Program.cs and go to the FillIoCContainer method and add code to conditional select the correct IFolder class when the application starts.

Quite simple really.

VN:F [1.9.3_1094]
Rating: 3.0/5 (1 vote cast)

Written by Will

February 3rd, 2010 at 9:39 am

Get Adobe Flash playerPlugin by wpburn.com wordpress themes