【问题标题】:Autofac IEnumerable resolve cause multiple constructionAutofac IEnumerable 解析导致多重构造
【发布时间】:2016-05-25 23:09:40
【问题描述】:

我有这个注册:

 builder.RegisterAssemblyTypes(assembly)
            .AsClosedTypesOf(typeof(IBusinessRule<>))
            .AsImplementedInterfaces()
            .SingleInstance();

我是这样解决的:

 using (var scope = Container.BeginLifetimeScope())
 {
        var rules = Container.Resolve<IEnumerable<IBusinessRule<T>>>();

        var result = rules.Select(x => x.IsValid(t));

        if (result.Any(x => !x.Successful))
        {
            var msg = string.Join(Environment.NewLine, result.Where(x => !x.Successful).Select(x => x.Message));

            return new OperationResultBase()
            {
                Message = msg,
                Successful = false,
                Operation = System.Reflection.MethodBase.GetCurrentMethod().Name
            };
        }
        else
        {
            return new OperationResultBase(true);
        }
  }

问题出在这一行:

var result = rules.Select(x => x.IsValid(t));

通过该解析,每个result 变量枚举都会调用实现IBusinessRule&lt;T&gt; 的类一次。

如果我在result 上调用ToList(),那么一切正常,只会调用一次。

调用ToList()是正确的方法还是注册有问题需要更改?

【问题讨论】:

    标签: c# dependency-injection autofac resolve generic-interface


    【解决方案1】:

    调用 ToList() 方法是否正确或注册有问题需要更改?

    不,您的注册没有问题。这是 Linq 的惰性求值属性。

    实际上它与autofac无关。一个普通的惰性 linq 查询的行为方式与您看到的完全相同。

    如果需要物化结果,需要调用ToListToArray。否则,将在每个枚举上评估查询(例如通过 foreach);

    【讨论】:

    • 我知道 Lazy 评估是有效的,但 Resolve 不应该真的解决而不是为将来的 REAL 解决提供参考?
    • @MohsenAfshin 解决只完成一次。重复动作是 Linq 行为的结果。在 var 结果 = rules.Select(x => x.IsValid(t));你没有任何枚举。接下来你做 result.Any 这意味着你做 rules.Select(x => x.IsValid(t)).Any() 然后再一次 result.Where 这意味着你做 rules.Select(x => x.IsValid( t)).哪里(...)。要打破这一点,您必须添加 ToList() 它将“缓存”您的验证结果。然后你会枚举这个'缓存'
    • @MohsenAfshin ATM 我现在无法访问 autofac 文档。我相信这在某处有记录。为了安全起见,我总是自己打电话给ToArray 来实现查询。
    猜你喜欢
    • 2016-08-15
    • 1970-01-01
    • 2012-06-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多