使用autofac为特定接口类型注册不同的依赖关系

本文关键字:依赖 关系 注册 接口类型 autofac 使用 | 更新日期: 2023-09-27 18:21:57

给定以下注册代码
ILogger采用单个字符串参数作为构造函数参数
IJob实现都将ILogger作为构造函数参数。

// register the 'default' logger.
builder.RegisterType<Logger>().As<ILogger>()
    .WithParameter(new NamedParameter("category", "default"));  

为了简洁起见,删掉了很多注册。。。

// register the 'job' logger. (this is a problem, a duplicate...)
builder.RegisterType<Logger>().As<ILogger>()
    .WithParameter(new NamedParameter("category", "job"));  
// register some classes that need a different logger parameter.
builder.RegisterAssemblyTypes(Assembly.GetExecutingAssembly())
    .Where(_ => typeof(IJob).IsAssignableFrom(_))
    // how to do this...
    .WithLoggerWithCategoryJob();

如何将category=default记录器用于除IJob之外的所有类注册
我想使用category=job记录器来完成所有这些。

使用autofac为特定接口类型注册不同的依赖关系

此解决方案演示了如何为记录器提供默认参数,以及如何仅为IRepository<>实现覆盖日志记录参数。

可以很容易地对代码进行增强,以根据实现的接口提供一组覆盖。

/// <summary>
/// The logging module.
/// </summary>
public class LoggingModule : Module
{
    /// <summary>
    /// Override to add registrations to the container.
    /// </summary>
    /// <remarks>
    /// Note that the ContainerBuilder parameter is unique to this module.
    /// </remarks>
    /// <param name="builder">The builder through which components can be registered.</param>
    protected override void Load(ContainerBuilder builder)
    {
        builder.RegisterType<NewLogger>()
            .As<ILogger>()
            .WithParameter(new NamedParameter("category", "Default"));
        base.Load(builder);
    }
    /// <summary>
    /// Override to attach module-specific functionality to a component registration.
    /// </summary>
    /// <remarks>
    /// This method will be called for all existing <i>and future</i> component
    /// registrations - ordering is not important.
    /// </remarks>
    /// <param name="componentRegistry">The component registry.</param><param name="registration">The registration to attach functionality to.</param>
    protected override void AttachToComponentRegistration(IComponentRegistry componentRegistry, IComponentRegistration registration)
    {
        registration.Preparing += (sender, args) =>
            {
                var type = args.Component.Activator.LimitType;
                if (type.GetInterfaces().All(_ => !_.IsGenericType || _.GetGenericTypeDefinition() != typeof(IRepository<>)))
                    return;
                var pm = new ResolvedParameter(
                    (p, c) => p.ParameterType == typeof(ILogger),
                    (p, c) => c.Resolve<ILogger>(new NamedParameter("category", "RepositoryLogger")));
                args.Parameters = args.Parameters.Union(new[] { pm });
            };
        base.AttachToComponentRegistration(componentRegistry, registration);
    }
}