views:

39

answers:

1

Hi folks,

I've got a windows application that creates some threads to parse some txt files. Nothing too crazy.

I'm using StructureMap Dependency Injection to create any instances of my Services and Repositories. So my Winform has a static property which returns the instance, based on what's been registered. Works great .. except I'm not sure when I should be disposing of my unit of work?

I've got a single UnitOfWork per thread. Now, the threads don't really stop. they keep on ticking over. Of course, the main Forms app is it's own thread, too .. and that doesn't stop until you kill it. So, i'm not sure when I should be disposing of the UnitOfWork (which then closes the context connection).

Traditionally, I've been doing web app programming (ASP.NET MVC now) so I can dispose at the end of the request ... and the same UnitOfWork was being used throughout that same request. That works nice ... But there is not end request, in a winform :(

Any ideas?

Here's some code to explain what I'm doing...

Registering my Repository classes...

public class EntityFrameworkRepositoryRegistry : Registry
{
    public EntityFrameworkRepositoryRegistry(string connectionString)
    {
        For<IUnitOfWork>()
                .HybridHttpOrThreadLocalScoped()
                .Use<SqlServerUnitOfWork>()
                .Ctor<string>("connectionString")
                    .Is(connectionString)
                .Ctor<ILoggingService>("loggingService")
                    .Is(new NLogLoggingService(GetType().ToString()))
                .SetProperty(x => x.EntityContainerName = "Entities");

        EntityFrameworkProfiler.Initialize(); // Hi Ayende :) Love this :)

        Scan(x =>
                    {
                        x.TheCallingAssembly();

                        x.ExcludeNamespaceContainingType<FakeContext>();

                        x.WithDefaultConventions();
                    }
            );
    }
}

and using the repository in the Form ... (yes, this should be a service, but i've not abstracted that out, just yet...

private static IUserRepository GetUserRepository()
{
    return ObjectFactory.GetInstance<IUserRepository>();
}

private void LoadUserInformation()
{
    DisplayText("Reading in active users... ", false);
    _users = GetUserRepository().Find().WhereIsActive().ToList();
    DisplayText("done.", false, true);
    DisplayText("Found " + _users.Count + " active users.");
}

.. now I can just call Dispose(); after I use call ToList() but then nothing else can use that UnitOfWork ???

Any ideas ?

A: 

I have not written many desktop apps, but the most common pattern I know of is to scope your unit of work to a screen (like a new or edit CRUD screen for example). It looks like your app is a single form though, so maybe you are fine with a single unit of work that lives for the lifetime of the application. Since the DataContext does not hold an open connection to the database, that should not be a problem.

The other option would be to use a unit of work per user action (every button click gets its own instance). If you decide to go that route, make sure your unit of work is registered as transient and manage the lifetime yourself.

Robin Clowers
I think i might go with 'action' while i have one screen .. and that screen is doing a lot of work.
Pure.Krome