【问题标题】:Autofac: Get constructor parameter after resolve (OnActivated/OnActivating)Autofac:解析后获取构造函数参数(OnActivated/OnActivating)
【发布时间】:2018-04-18 09:36:28
【问题描述】:

我有以下结构:

class SomeViewModel
{
    public SomeViewModel(SomeService service)
    {
        service.SetViewModel(this); // <- Move this call to Autofac
    }
}

class SomeService
{
    public void SetViewModel(object viewModel) 
    {
        //...
    }
}

我不想在每个 ViewModel 中手动调用 service.SetViewModel,而是希望将此调用移至 IoC 容器 (Autofac)。我试过使用OnActivated,但没有可用的参数:

builder.Register<SomeViewModel>
    .AsSelf()
    .OnActivated(e =>
        {
            var service = e.Parameters
                .OfType<SomeService>()
                .FirstOrDefault(); // <- There are no parameters
            service.SetViewModel(e.Instance);
        });

是否可以将SomeViewModel 构造函数中的调用service.SetViewModel(this); 移动到某种Autofac 注册中?

【问题讨论】:

  • 通常最好以依赖关系图变为非循环的方式重构代码。循环依赖图是一种设计味道。
  • 没有任何Parameters,因为我猜你没有调用Resolve&lt;T&gt; 并指定任何-Resolve&lt;T&gt;(param1, param2...)。这些参数是解析参数,而不是构造函数参数。
  • 谢谢@TravisIllig,这是我正在寻找的信息。我认为Parameters 代表构造函数参数。

标签: c# dependency-injection inversion-of-control autofac ioc-container


【解决方案1】:

我同意@Steven。但是即使我们把它分开,如果有几个视图模型共享同一个服务怎么办?哪一个将获得服务 - “最后的胜利”?你会想再仔细考虑一下这个设计。

现在您已被警告...您的解决方案可能如下:

        ...
        builder.Register(s => CreateViewModel(s, svc => new SomeViewModel(svc))).AsSelf();
    }

    private T CreateViewModel<T>(IComponentContext ctx, Func<SomeService, T> createInstance) {
        var svc = ctx.Resolve<SomeService>();
        var instance = createInstance(svc);
        svc.SetViewModel(instance);
        return instance;
    }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-02-28
    • 1970-01-01
    相关资源
    最近更新 更多