4

我主要使用 Ninject,所以如果我混淆了术语,我深表歉意。

我创建了一个记录器模块来使用目标类名称作为记录器名称来处理 NLog。它与此非常相似:http ://docs.autofac.org/en/latest/examples/log4net.html?highlight=log4net

我还在服务层中创建了一个模块,负责处理所有服务级别的注册。看起来像这样:

public class ServiceModule : Module
{
    protected override void Load(ContainerBuilder builder)
    {
       builder.Register(x => new AccountService(x.Resolve<ILogger>()))
            .As<IAccountService>()
            .InstancePerRequest();
    }
}

这是我的autofac注册:

var builder = new ContainerBuilder();

builder.RegisterControllers(Assembly.GetExecutingAssembly());
builder.RegisterModule(new LoggingModule());
builder.RegisterModule(new ServiceModule());

var container = builder.Build();
DependencyResolver.SetResolver(new AutofacDependencyResolver(container));

app.UseAutofacMiddleware(container);
app.UseAutofacMvc();

在运行时,我收到一个异常说 ILogger 尚未注册,我是否遗漏了有关模块如何工作导致 ILogger 在我的服务模块中不可见的一些内容?

4

1 回答 1

2

一个模块可以做很多事情:它可以注册新组件和/或订阅Autofac事件。

在这种情况下,LoggingModule不注册ILog。它使用事件拦截其他组件的准备,Preparing并添加一个新Parameter的,ILog如果需要的话。

您将无法解决ILog,但如果您的AccountService实施需要ILog以下Parameter将被触发并提供ILog实施。

new ResolvedParameter(
    (p, i) => p.ParameterType == typeof(ILog),
    (p, i) => LogManager.GetLogger(p.Member.DeclaringType)
)

您所要做的就是注册您的类型而不尝试显式创建实例:

builder.RegisterType<AccountService>()
       .As<IAccountService>()
       .InstancePerRequest();
于 2016-05-09T08:16:22.470 回答