Reputation: 573
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
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
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