Reputation: 1145
I have a little problem with Autofac configuration. My goal is to create new EFContext
per ViewModel
Right now I have:
ContainerBuilder builder = new ContainerBuilder();
builder.Register(ctx => new EFContext())
.InstancePerLifetimeScope();
builder.Register<FirstService>(c => new FirstService(c.Resolve<EFContext>()));
builder.Register<SecondService>(c => new SecondService(c.Resolve<EFContext>()));
builder.Register<OtherService>(c => new OtherService(c.Resolve<EFContext>()));
builder.Register<FirstViewModel>(c =>
new FirstViewModel(
c.Resolve<FirstService>(),
c.Resolve<SecondService>(),
c.Resolve<OtherService>()
));
builder.Register<SecondViewModel>(c =>
new SecondViewModel(
c.Resolve<FirstService>(),
c.Resolve<SecondService>(),
c.Resolve<OtherService>()
));
But now when I create SecondViewModel
all services get the same EFContext
as in FirstViewModel
services
Upvotes: 2
Views: 1366
Reputation: 741
I've made another attempt, and I think this is currently the best solution I can find.
Could you try and see if the following works for you (from the Autofac Documentation)?
//First builder
ContainerBuilder builder = new ContainerBuilder();
//Register context as Lifetime dependent.
builder.Register(ctx => new EFContext())
.InstancePerLifetimeScope();
//Register services.
builder.Register<FirstService>(c => new FirstService(c.Resolve<EFContext>()));
builder.Register<SecondService>(c => new SecondService(c.Resolve<EFContext>()));
builder.Register<OtherService>(c => new OtherService(c.Resolve<EFContext>()));
//Build first builder to work with scopes.
var container = builder.Build();
//Create a second builder.
ContainerBuilder builder2 = new ContainerBuilder();
using (var scope = container.BeginLifetimeScope())
{
//Create services, since lambda is executed after scope is disposed.
var firstService = scope.Resolve<FirstService>();
var secondService = scope.Resolve<SecondService>();
var otherService = scope.Resolve<OtherService>();
//Register viewmodel with second builder.
builder2.Register<FirstViewModel>(c => new FirstViewModel(
firstService,
secondService,
otherService
));
}
using (var scope = container.BeginLifetimeScope())
{
//Create services, since lambda is executed after scope is disposed.
var firstService = scope.Resolve<FirstService>();
var secondService = scope.Resolve<SecondService>();
var otherService = scope.Resolve<OtherService>();
//Register viewmodel with second builder.
builder2.Register<SecondViewModel>(c => new SecondViewModel(
firstService,
secondService,
otherService
));
}
//Build second builder.
var container2 = builder2.Build();
//Merge registration of second builder with the first.
foreach (var registration in container2.ComponentRegistry.Registrations)
container.ComponentRegistry.Register(registration);
//Resolve the viewmodels from the container.
var firstViewModel = container.Resolve<FirstViewModel>();
var secondViewModel = container.Resolve<SecondViewModel>();
An issue could be that the services (FirstService
, SecondService
and OtherService
) are resolved in mid-registration of components using a LifetimeScopes
, which might affect more advanced dependency structures with LifetimeScopes
.
Upvotes: 2
Reputation: 1145
OK, I have my answer
There wasn't any problem with Autofac configuration but in resolving dependency. Right now I have:
ContainerBuilder builder = new ContainerBuilder();
builder.Register(ctx => new EFContext())
.InstancePerLifetimeScope();
builder.Register<FirstService>(c => new FirstService(c.Resolve<EFContext>()));
builder.Register<SecondService>(c => new SecondService(c.Resolve<EFContext>()));
builder.Register<OtherService>(c => new OtherService(c.Resolve<EFContext>()));
builder.Register<FirstViewModel>(c =>
new FirstViewModel(
c.Resolve<FirstService>(),
c.Resolve<SecondService>(),
c.Resolve<OtherService>()
));
builder.Register<SecondViewModel>(c =>
new SecondViewModel(
c.Resolve<FirstService>(),
c.Resolve<SecondService>(),
c.Resolve<OtherService>()
));
And when I want resolve dependency I use:
using (var scope = Container.BeginLifetimeScope())
{
var vm = scope.Resolve<FirstViewModel>();
}
Upvotes: 2