Gradinariu Cezar
Gradinariu Cezar

Reputation: 573

Autofac, Console app and UnitOfWork

I have a console application - Worker - that listens for messages that come in from a queing system, and performs some tasks that involve database access for each of the messages. I use EF 6 to access the MSSQL db and in my implementation I use Unit of work. My DI container is Autofac - I am new to it -, and I use it to bind among many other things the IUnitOfWork to UnitOfWork.

The problem I have here and I do not know how to deal with is: I want a new UnitOFWork instance for every message, so it cannot be Singleton, but during the same message processing I need the same instance of UnitOfWork, so it cannot be -Instance Per Dependency-.

Thank you.

Upvotes: 1

Views: 671

Answers (2)

BatteryBackupUnit
BatteryBackupUnit

Reputation: 13243

Alternatively to using the container directly as shown by @MaDeRkAn's answer you can also use an Func<Owned<IUnitOfWork>> instead:

containerBuilder
    .RegisterType<UnitOfWork>()
    .As<IUnitOfWork>()
    .InstancePerLifetimeScope();

public class MessageQueueWorker
{
    private Func<Owned<IUnitOfWork>> unitOfWorkFactory;

    public MessageQueueWorker(Func<Owned<IUnitOfWork>> unitOfWorkFactory)
    {
        this.unitOfWorkFactory = unitOfWorkFactory
    }

    public void ProcessMessage(message)
    {
        using (Owned<IUnitOfWork> unitOfWork = this.unitOfWorkFactory())
        {
            //access the actual IUnitOfWork with the .Value property
            unitOfWork.Value.DatabaseTable....

            // when the using scope ends the IUnitOfWork and all it's
            // "non shared" dependencies will be disposed
        }
    }
}

Hint: regarding the "non shared" dependencies: these are the ones with the same or shorter scope than IUnitOfWork has. A SingleInstance injected into IunitOfWork would not be disposed, of course.

Upvotes: 2

Erkan Demirel
Erkan Demirel

Reputation: 4382

You should register it as Instance Per Lifetime Scope

When message comes, you should begin new Lifetime Scope and resolve your IUnitOFWork in there. That's way you will have 1 UnitOFWork object in that lifetimescope.

Your register should be like this:

builder.RegisterType<UnitOfWork>().As<IUnitOfWork>().InstancePerLifetimeScope();

And you should resolve IUnitOfWork like this:

var message=GetMessageFromBus();
using(var myLifetime = container.BeginLifetimeScope())
{
    var myUnitOFWork = myLifetime.Resolve<IUnitOfWork>();
}

Upvotes: 1

Related Questions