繁体   English   中英

解决Module类中的AutoFac依赖项

[英]Resolving AutoFac dependencies inside Module class

我是AutoFac的新手,目前我在app app中使用自定义模块来启动一些核心F#系统。 我正在使用的代码是

var builder = new ContainerBuilder();
builder.RegisterType<DefaultLogger>().As<IDefaultLogger>();
builder.RegisterModule(new ConfigurationSettingsReader("autofac"));
builder.Build();

在我的app配置中,我有适当的逻辑来启动相关系统。 我想访问我的模块中的DefaultLogger。 Module基类的元数据有以下选项可供我使用:

protected virtual void AttachToComponentRegistration(IComponentRegistry componentRegistry, IComponentRegistration registration);

protected virtual void AttachToRegistrationSource(IComponentRegistry componentRegistry, IRegistrationSource registrationSource);

public void Configure(IComponentRegistry componentRegistry);

protected virtual void Load(ContainerBuilder builder);

到目前为止我只使用Load,我在构建器上看不到任何允许我进入日志记录服务的方法。

使用autofac而不是使用RegisterType方法在模块中注册某些内容时,可以使用Register方法:

builder.Register(c =>
   {
       IComponentContext ctx = c.Resolve<IComponentContext();
       IDefaultLogger logger = ctx.Resolve<IDefaultLogger>();
       ...do something with logger...
       return ...return object you want to register...;
    });

答案结果非常简单。 我刚刚将IComponentContext添加为Module的实现的依赖项

public class LocalActorSystemModule : Module {
    private IComponentContext m_ComponentContext; // A service for resolving dependencies required by this module

    public LocalActorSystemModule(IComponentContext componentContext) { 
        m_ComponentContext = componentContext;
    }

让AutoFac为我注入IComponentContext。 这样我就可以解决模块内部所需的任何依赖关系。

使用每个IoC / DI容器的经验法则: 解决一次! =>然后,您将获得所请求对象的所有依赖项。 如果你试图多次解决,注册其他对象(在此期间)你陷入了地狱。 真。 如果您想在不同的地点和时间点(从中央注册解析)检索不同目的的对象,您可能正在寻找服务定位器模式 (但这通常也被描述为反模式 )。

模块的目的是将相关注册(有条件地)捆绑为Autofac文档中的statet

模块是一个小类,可用于在“Facade”后面捆绑一组相关组件,以简化配置和部署。

...因此,如果它们只是注册的总和并且容器尚未构建,则您无法立即解析和使用(甚至以前注册过的)组件(除了通过OnActivate *钩子在注册者本身上调用方法之外)当使用实例注册时,但我认为这不是你的例子的情况)。 组件处于注册状态,但完整的上下文尚未准备好解决。 如果您覆盖另一个模块中的注册会发生什么? 然后你会注入不同的对象......糟糕的主意。 也许您应该重新考虑您的应用程序设计以及哪些对象具有哪些职责。

顺便说一句:日志记录是一个跨领域的问题,通常通过调用单独的静态工厂或服务而不是执行构造函数/属性注入来“注入/解决”(例如,参见Common.Logging的用法)。

public class MyModule : Module
{
    private static readonly ILog Log = LogManager.GetLogger<MyModule>();

    protected override void Load(ContainerBuilder builder)
    {
        Log.Debug(msg => msg("Hello")); // log whatever you want here
    }
}

您还可以尝试使用AOP库并将依赖项编织到模块中(使用反射)。 但我认为仅仅尝试登录模块是不值得的。

无论如何:@ mr100已经在注册过程中显示了正确的用法。 在那里你也可以处理激活等但不能记录模块本身。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM