每个viewmodel的Autofac实例

时间:2014-12-01 09:45:17

标签: c# wpf mvvm inversion-of-control autofac

我对Autofac配置有点问题。我的目标是根据EFContext

创建新的ViewModel

现在我有:

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>()
            ));

但现在,当我创建SecondViewModel时,所有服务都与EFContext服务中的FirstViewModel相同

2 个答案:

答案 0 :(得分:2)

我已经做了另一次尝试,我认为这是我能找到的最佳解决方案。

您可以尝试查看以下内容是否适用于您(来自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>();

问题可能是服务(FirstServiceSecondServiceOtherService)在使用LifetimeScopes的组件中间注册时得到解决,这可能会影响更高级LifetimeScopes的依赖结构。

答案 1 :(得分:2)

好的,我有答案

Autofac配置没有任何问题,但解决依赖性问题。现在我有:

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>()
            ));

当我想要解析依赖时,我使用:

using (var scope = Container.BeginLifetimeScope())
{
    var vm = scope.Resolve<FirstViewModel>();
}