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

时间:2014-09-16 07:42:30

标签: c# asp.net-mvc autofac

鉴于以下注册码...
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记录器。

1 个答案:

答案 0 :(得分:0)

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

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

/// <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);
    }
}