【问题标题】:Autofac passing parametersAutofac 传递参数
【发布时间】:2019-08-19 12:17:36
【问题描述】:

假设我有一个带有相应实现的 IConfigurationService 接口:

public class JsonConfigurationService : IConfigurationService

构造函数如下所示:

public JsonConfigurationService(string filePath, ILoggingService loggingService)

我想使用 Autofac 进行依赖注入,但我不确定如何处理 JsonConfigurationService 的构造函数参数。对于 ILoggingService 我已经添加了这样的注册 - 所以没有问题:

builder.RegisterType<NlogService>().As<ILoggingService>();

但是如何将filePath 参数提供给JsonConfigurationService 的构造函数。我已经阅读了诸如“NamedParameter”、“TypedParameter”或“ResolvedParameter”之类的选项,但对所有这些选项来说,仍然有一种不好的感觉。

  • NamedParameter:如果有人在之后重命名参数怎么办
  • TypedParameter:如果之后添加了另一个相同类型的参数
  • ResolvedParamter:嗯,两者的混合

有没有更好的方法来处理这个问题或一种最佳实践?

【问题讨论】:

  • 该值是编译时的常量吗?它是否在运行时解决,如果是,从哪里解决?
  • 运行时解决
  • 从哪里来的?....

标签: c# autofac


【解决方案1】:

假设你的filePath 在编译时是已知的,有几个选项,但这真的归结为个人喜好,因为它们都是有利有弊的体面方法。为了安全起见,我至少会推荐一些涵盖关键服务解析的基本单元测试。通过测试,使用 NamedParameter 可能仍然感觉不完全正确,但实际上没问题。

另一种方法是使用 lambda 进行注册,例如

builder.Register(c => new JsonConfigurationService(@"c:\somepath\", c.Resolve<ILoggingService>()));

如果您的 JsonConfigurationService 依赖项出现问题,这显然会变得更加棘手,但至少您可以进行编译时检查。

另一种方法是抽象出另一种类型后面的字符串并使用 TypedParameter。有些人会认为它是不必要的代码,但 IMO 如果它有助于提高可读性,即使只是在注册的上下文中,它也可能是值得的:

public interface IFilePathProvider
{
    string FilePath { get; }
}
public class FilePathProvider : IFilePathProvider
{
    public string FilePath => @"c:\";
}


public JsonConfigurationService(IFilePathProvider filePathProvider, ILoggingService loggingService)

如果您最终从 config 中读取该参数,或者如果它在代码中的其他地方使用,那么该抽象本身甚至可能有意义。

这取决于具体情况和一些偏好 - 不确定是否有涵盖所有场景的明确最佳实践。

编辑 - 注意文件路径是在运行时确定的,可能值得一读:Injecting Runtime Components。据此,如果仅在启动时设置,类似的原则仍然适用。如果稍后确定路径,那么可能值得考虑将其作为构造函数参数完全删除。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-08-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多