在Castle Windsor中能否无需显式注册即可注入命名组件?
解决方案:Castle Windsor下优雅实现共享日志实例注入
方案1:使用Typed Factory Facility(推荐)
这是Castle Windsor官方提供的工厂实现方案,无需手动编写工厂类,框架会自动生成代理实现,同时支持同名日志实例单例复用。
首先定义日志工厂接口:
public interface ILoggerFactory { ILogger GetLogger(string name); }
然后配置容器,注册Typed Factory和ILogger的创建逻辑:
// 添加Typed Factory设施 container.AddFacility<TypedFactoryFacility>(); container.Register( // 注册ILogger,指定单例生命周期,通过工厂方法动态传入名称 Component.For<ILogger>() .ImplementedBy<Logger>() .LifestyleSingleton() .UsingFactoryMethod((kernel, context) => { var loggerName = context.AdditionalArguments["name"] as string; return new Logger(loggerName); }), // 注册工厂接口,关联自定义参数选择器 Component.For<ILoggerFactory>() .AsFactory() .Configure(f => f.SelectedWith(new LoggerFactorySelector())) ); // 自定义参数选择器,将工厂方法的参数传递给ILogger构造 public class LoggerFactorySelector : DefaultTypedFactoryComponentSelector { protected override IDictionary<string, object> GetArguments(MethodInfo method, object[] arguments) { if (method.Name == "GetLogger" && arguments.Length == 1) { return new Dictionary<string, object> { { "name", arguments[0] } }; } return base.GetArguments(method, arguments); } }
在业务组件中直接注入工厂获取指定名称的日志实例,同名实例会自动复用:
public class MyClass : IMyClass { private readonly ILogger _logger; public MyClass(ILoggerFactory loggerFactory) { _logger = loggerFactory.GetLogger("magicstring"); } }
方案2:注册命名ILogger组件(适合固定少量日志名称)
如果只需要少数固定名称的共享日志,可以直接注册命名的ILogger组件,由Windsor自动实例化,避免手动new:
container.Register( // 注册名为"magicstring"的ILogger,单例,自动注入构造参数 Component.For<ILogger>() .ImplementedBy<Logger>() .LifestyleSingleton() .Named("magicstring") .DependsOn(Dependency.OnValue("name", "magicstring")), // 业务组件依赖该命名日志实例 Component.For<IMyClass>() .ImplementedBy<MyClass>() .DependsOn(Dependency.OnComponent(typeof(ILogger), "magicstring")) );
这种方式下,所有依赖"magicstring"命名ILogger的组件都会拿到同一个单例实例,且由容器负责对象生命周期管理。
方案3:直接指定构造参数(适合单个组件场景)
如果只有个别组件需要特定日志,可直接在组件注册时传入构造参数:
container.Register( Component.For<IMyClass>() .ImplementedBy<MyClass>() .DependsOn(Dependency.OnValue<ILogger>(new Logger("magicstring"))) );
若Logger存在其他依赖项,Windsor会自动解析并注入,比手动实例化更灵活。
内容的提问来源于stack exchange,提问作者John V
相关产品推荐
相关产品推荐

