Reusable Unit Of Work Interface / Factory
Leaky Abstractions

public interface IUnitOfWork : IDisposable
{
    void Commit();
}


I like that there's only a Commit method here - it makes the IUnitOfWork interface very well segregated/focused. However the interface specifying that all implementations must also implement IDisposable, is a leaky abstraction - you have a specific implementation in mind, and that implementation is leaking into the abstraction: what if I wanted a mock-up implementation that doesn't need to be disposed?

public interface IUnitOfWorkFactory
{
    IUnitOfWork GetUnitOfWork(IsolationLevel isolationLevel);
}


GetUnitOfWork makes it sound like the &quot;factory&quot; is hiding a Singleton or something (the name is reminiscent of &quot;GetInstance&quot;) - I like my abstract factories when they expose a single parameterless Create method, and intake their dependencies from the constructor; IsolationLevel is also an implementation detail that's leaking into an abstraction - one specific implementation requires an &quot;isolation level&quot;, and that implementation detail is leaked into the abstraction.
I would move : IDisposable to TransactionScopeUnitOfWork, because that specific implementation must implement IDisposable.
Then I'd change the abstract factory interface to look something like this:
public interface IUnitOfWorkFactory
{
    IUnitOfWork Create();
}

And the specific implementation that creates a TransactionScopeUnitOfWork would be responsible for specifying an IsolationLevel:
public class TransactionScopeUnitOfWorkFactory : IUnitOfWorkFactory
{
    private readonly IsolationLevel _isolationLevel;

    public TransactionScopeUnitOfWorkFactory(IsolationLevel isolationLevel)
    {
        _isolationLevel = isolationLevel;
    }

    public IUnitOfWork Create()
    {
        return new TransactionScopeUnitOfWork(_isolationLevel);
    }
}

With IoC Containers such as Ninject, you can easily specify IsolationLevel.Serializable or IsolationLevel.ReadCommitted as needed, depending on whether the factory dependency is being injected into a Smurf or into a FooBar's constructor.
That said I've noticed I seldom need to actually implement an abstract factory with Ninject: you can easily configure DI to inject the result of an anonymous method whenever a class has an IUnitOfWork dependency to be constructor-injected: you just do the binding with .ToFactory and let Ninject do the hard work.
The client code shouldn't be bothered with configuring a transaction isolation level if all it needs to care for is that it's depending on an IUnitOfWork that provides a Commit method; if the client code needs to know about an isolation level, then it knows more than it should about the implementation behind the interface it's presented.